52

我有一个对象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)
4

7 回答 7

120

您应该使用getattr包装器而不是直接检索id.

a = getattr(myobject, 'id', None)

这就像说“我想id从对象中检索属性,但如果对象内部myobject没有属性,则改为返回。” 但它有效地做到了。idmyobjectNone

一些对象还支持以下形式的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) 开始,然后递归地为您尝试访问 using 的每个属性深入了解getattr,所以在您的问题中,它会是这样的:

a = getattr(getattr(myobject, 'id', None), 'number', None)

于 2013-02-17T16:52:59.650 回答
11

最简单的方法是使用三元运算符:

a = myobject.id if myobject is not None else None

如果中间值为真,则三元运算符返回第一个表达式,否则返回后一个表达式。

请注意,您也可以使用异常以另一种方式执行此操作:

try:
    a = myobject.id
except AttributeError:
    a = None

这符合 Pythonic 的理想,即请求宽恕比请求许可更容易——什么是最好的取决于具体情况。

于 2013-02-17T16:49:44.263 回答
6

在我的对象类中,您可以覆盖

class Foo(object):
   def __getattribute__(self, name):
      if not name in self;
        return None;
      else:
        # Default behaviour
        return object.__getattribute__(self, name)
于 2013-02-17T16:57:12.743 回答
4

如果您想解决类定义中的问题myobject(如Black Diamond 的答案),您可以简单地定义__getattr__为 return None

class Myobject:
    def __getattr__(self, name):
        return None

这是有效的,因为__getattr__仅在尝试访问不存在的属性时才调用,而__getattribute__无论属性的名称如何,总是首先调用。(另请参阅此 SO 帖子。)

尝试:

myobject = Myobject()
print myobject.id 
myobject.id = 7
print myobject.id
于 2017-06-30T18:38:37.113 回答
3

关于内置模块内置函数 getattr 的帮助:

getattr(...)
    getattr(object, name[, default]) -> value

从对象中获取命名属性;getattr(x, 'y') 等价于 xy 给定默认参数时,当属性不存在时返回;没有它,在这种情况下会引发异常。

以下应该工作:

a = getattr(myobject, 'id', None)
于 2013-02-17T16:55:21.820 回答
0
try:
    a = myobject.id
except AttributeError:
    a = None

也可以工作并且更清晰,IMO

于 2013-02-17T16:51:17.943 回答
0
a=myobect.id if myobject else None
于 2013-02-17T16:53:54.403 回答