myobject
を返すオブジェクトNone
があります。 None
を返す場合、属性id
を返しません。
a = myobject.id
したがって、myobjectがNone
の場合、上記の文はAttributeError
になります。
AttributeError: 'NoneType' object has no attribute 'id'
myobject
がNoneの場合、a
がNone
と等しくなるようにします。次のような1行のステートメントでこの例外を回避するにはどうすればよいですか。
a = default(myobject.id, None)
getattr
の値を直接取得する代わりに、 id
ラッパーを使用する必要があります。
_a = getattr(myobject, 'id', None)
_
これは、「オブジェクトid
から属性myobject
を取得したいが、オブジェクトid
内に属性myobject
がなければ、代わりにNone
を返します。」しかし、それは効率的に行われます。
一部のオブジェクトは、次の形式のgetattr
アクセスもサポートしています。
_a = myobject.getattr('id', None)
_
OPリクエストごとに、 'deep getattr' :
_def deepgetattr(obj, attr):
"""Recurses through an attribute chain to get the ultimate value."""
return reduce(getattr, attr.split('.'), obj)
# usage:
print deepgetattr(universe, 'galaxy.solarsystem.planet.name')
_
簡単な説明:
Reduce は、インプレース再帰関数のようなものです。この場合の処理はobj
(ユニバース)で始まり、getattr
を使用してアクセスしようとする属性ごとに再帰的に深くなるため、質問では次のようになります。
a = getattr(getattr(myobject, 'id', None), 'number', None)
最も簡単な方法は、三項演算子を使用することです:
a = myobject.id if myobject is not None else None
三項演算子は、中間値が真の場合は最初の式を返し、そうでない場合は後者の式を返します。
例外を使用して、別の方法でもこれを行うことができることに注意してください。
try:
a = myobject.id
except AttributeError:
a = None
これは、許可よりも許しを求める方が簡単であるというPythonの理想に適合します。最適なものは状況によって異なります。
私のオブジェクトクラスでは、オーバーライドを置くことができます
class Foo(object):
def __getattribute__(self, name):
if not name in self;
return None;
else:
# Default behaviour
return object.__getattribute__(self, name)
モジュール組み込みの組み込み関数getattrのヘルプ:
getattr(...) getattr(object, name[, default]) -> value
オブジェクトから名前付き属性を取得します。 getattr(x、 'y')はx.yと同等です。デフォルト引数が指定されている場合、属性が存在しないときに返されます。それがないと、その場合に例外が発生します。
以下が動作するはずです:
a = getattr(myobject, 'id', None)
myobject
のクラスの定義で問題を解決したい場合( Black Diamond's answer など)、単に__getattr__
はNone
を返します:
class Myobject:
def __getattr__(self, name):
return None
これは、__getattr__
は、存在しない属性にアクセスしようとしたときにのみ呼び出されますが、__getattribute__
は、属性の名前に関係なく常に最初に呼び出されます。 ( this SO post も参照してください。)
試すには:
myobject = Myobject()
print myobject.id
myobject.id = 7
print myobject.id
a=myobect.id if myobject else None
try:
a = myobject.id
except AttributeError:
a = None
動作し、より明確になります、IMO