我有一个对象myobject
,可能会返回None
。如果它返回None
,则不会返回属性id
:
a = myobject.id
因此当myobject为None
时,上面的结果会导致AttributeError
:
AttributeError: 'NoneType' object has no attribute 'id'
如果myobject
为无,则我希望a
等于None
。如何在一行语句中避免此异常,例如:
a = default(myobject.id, None)
答案 0 :(得分:85)
您应该使用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
(Universe)开始,然后递归加深您尝试使用getattr
访问的每个属性,所以在您的问题中它将是这样的:
a = getattr(getattr(myobject, 'id', None), 'number', None)
答案 1 :(得分:10)
最简单的方法是使用三元运算符:
a = myobject.id if myobject is not None else None
如果中间值为true,则三元运算符返回第一个表达式,否则返回后一个表达式。
请注意,您也可以使用例外以其他方式执行此操作:
try:
a = myobject.id
except AttributeError:
a = None
这符合Pythonic的理想,即要求宽恕比获得更容易 - 最好的将取决于具体情况。
答案 2 :(得分:6)
在我的对象类中,您可以将覆盖
class Foo(object):
def __getattribute__(self, name):
if not name in self;
return None;
else:
# Default behaviour
return object.__getattribute__(self, name)
答案 3 :(得分:2)
帮助内置函数getattr in module builtins:
getattr(...) getattr(object, name[, default]) -> value
从对象获取命名属性; getattr(x,'y')相当于x.y. 如果给出了默认参数,则在属性不返回时返回 存在;没有它,在这种情况下会引发例外。
以下应该工作:
a = getattr(myobject, 'id', None)
答案 4 :(得分:1)
如果您想在test
类的定义中解决问题(例如在Black Diamond's answer中),您只需定义myobject
即可返回__getattr__
:
None
这是有效的,因为class Myobject:
def __getattr__(self, name):
return None
仅在尝试访问不存在的属性时被调用,而__getattr__
始终首先被调用,无论属性的名称如何。 (另见this SO post。)
尝试:
__getattribute__
答案 5 :(得分:0)
try:
a = myobject.id
except AttributeError:
a = None
IMO
也会更有效,更清晰答案 6 :(得分:0)
a=myobect.id if myobject else None