2012-02-09 5 views
1

存在しない可能性がオブジェクトの属性のコンディショニング: Pythonの:私はこのように見えた条件コードのビットを持っていた

if self.above and self.above.author and self.above.author.username!=self.author.username: 
    "notify above.author that someone has replied to their comment" 

しかし

self.aboveかが存在しない場合は、コメントのいずれかには、著者を持っていない場合

AttributeError: 'NoneType' object has no attribute 'author' 

または

AttributeError: 'NoneType' object has no attribute 'username' 

ので、私は前に最初に確認することができます。そして、私のようなエラーが出ますそれらの属性

if self.above: 
    if self.above.author: 
     if self.author: 
      if self.author.username!=self.above.author.username: 
       "notify about response" 
     else: 
      "notify about response" 

のためではなく、すべての余分なIFSと「通知応答に関する」コードの重複を見て、行数は倍以上です。この問題が発生すると、多くの時間がかかるので、上記のソリューションを使用すると、いくつかの単純な条件をチェックするために50行の余分なコードが必要になります。

これを処理するより良い方法はありますか?

答えて

1

ファクタすべてのオブジェクト属性は、欠落している属性を正常に処理する関数にルックアップします。 self.above.author.usernameが見つからない場合は、self.aboveが不足しているのと同じ状況です。あなたは気にしません。あなたは滑走路を使い果たしました。

def resolve(obj, path): 
    """Resolves an attribute path on an object, returning `None` 
     if any attribute is not found""" 
    for name in path.split("."): 
     obj = getattr(obj, name, None) 
     if obj is None: 
      break 
    return obj 

selfauthor = resolve(self, "author.username") 
aboveauthor = resolve(self, "above.author.username") 

if not selfauthor or (selfauthor and selfauthor != aboveauthor): 
    "notify about response" 

あなたも、それは立派だが、ベースクラス上のどこかresolve()方法を置くことができます。

self.resolve("above.author.username") # etc 
+0

私が見逃しているより大きい知恵がない限り、これはちょうど[NIH](http://en.wikipedia.org/wiki/Not_invented_here)のような例外処理を行うilisticのように見えるので、私はdownvoteする傾向があります。 – Kimvais

+0

この部分 'self.above.author.username!= self.author.username'はユーザ名の値が同じでないことをチェックしています。あなたの' resolve'関数はこれらの値を返しません。 – vikki

+0

非常に良い。これは私が元々望んでいた振る舞いを正確に得ることを可能にします。よく書かれました。ありがとう。 – Hank

1

おそらくhandling the AtributeErrorを試してみてください。また、「応答通知」コードを関数にしたいので、そこにコードを複製する必要はありません。たとえば、

def notify(who, about_what): 
    "notify who that about_what happened" 

try: 
    if self.above.author.username!=self.author.username: 
     notify(self.above.author.username, "someone replied to a comment") 
except AttributeError: 
    notify(someone, "something went wrong") 

また、「応答に関する通知」コードを関数にしたいので、そこでコードを複製する必要はありません。

+0

方法は、「もし」ステートメントよりも良いということでしょうか? – WeaselFox

+1

@WeaselFoxあなたはそれを一度(ネストされていない場合)処理する必要があります。これはPythonのダック型のパラダイムと一貫しています - http://docs.python.org/glossary.html#term-duck-typing – Hamish

+1

@WeaselFox Plus、Pythonではif文ではなく例外を使用する方が望ましいです。許可よりも許してほしいと思う方が簡単です(http://docs.python.org/glossary.html#term-eafp)。 –

関連する問題