0

このコードを見てください:

>>> class c(object):
...    pass
... 
>>> a=c()
>>> if a.b.c:
...    print 'hello'
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'c' object has no attribute 'b'

静かな!これは問題ではありません。読み続けてください:

誰かがエンタープライズソフトウェアを開発するとき(たとえば、djangoを使用)、ビジネスルールを作成する必要があります。このルールは次のようになります

if invoice.customer.adress.country in ...:
    invoice.makeSomeSpecialOffer()

しかし、表現に関係するオブジェクトの1つが存在しない場合があります。次に、エラーを回避するために、文を次のように書き直します。

if invoice.customer and
   invoice.customer.adress and
   invoice.customer.adress.country and
   invoice.customer.adress.country in ...

これは読みにくいです!(hasattrで試すこともできますが、読みにくくなります)。

私の回避策はifステートメントを試してみることですが、この種のエラーを回避するためのよりエレガントな、またはピタトニックな方法はありますか?あなたの好きなテクニックはどれですか?

4

2 に答える 2

2

連鎖属性を確認するには、次の関数が役立つ場合があります。

def get_chainedattr(parobj, *args):
    try:        
        ret = parobj
        for arg in args:
            ret = getattr(ret, arg)   
        return ret
    except AttributeError:
        return None

読みやすいかどうかはわかりませんが、この関数を使用すると、例を次のように書くことができます。

if get_chainedattr(invoice, "customer", "adress", "country") in ...:
   invoice.makeSomeSpecialOffer()
于 2011-12-10T17:10:10.657 に答える
1

これは読みにくい!(また、hasattr を試すこともできますが、読みにくくなります)。

try別のオプションは、 'exceptブロックで囲むことです。

try:
    if invoice.customer.adress.country in ...:
        invoice.makeSomeSpecialOffer()
except AttributeError:
    None

プロアクティブなチェックを行うhasattrか、try-except のようなリアクティブを行うことができます。読みやすさは認識であり、両方のアプローチは例外的です。

于 2011-12-10T15:54:45.020 に答える