如何为属性返回默认值?

64 投票
7 回答
53779 浏览
提问于 2025-04-17 16:10

我有一个对象 myobject,它可能会返回 None。如果返回的是 None,那么就不会有一个叫 id 的属性:

a = myobject.id

所以当 myobjectNone 的时候,上面的代码就会导致一个 AttributeError 错误:

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

如果 myobjectNone,那么我希望 a 也等于 None。我该怎么用一行代码来避免这个错误,比如:

a = default(myobject.id, None)

7 个回答

7

在我的对象类中,你可以使用重写功能。

class Foo(object):
   def __getattribute__(self, name):
      if not name in self;
        return None;
      else:
        # Default behaviour
        return object.__getattribute__(self, name)
11

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

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

三元运算符的意思是,如果中间的值为真,就返回第一个表达式;如果为假,就返回第二个表达式。

另外,你也可以用另一种方式来实现这个功能,那就是使用异常:

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

这符合Python的一个理念:有时候请求原谅比请求许可更简单——具体用哪种方法最好,还是要看具体情况。

142

你应该使用getattr这个方法,而不是直接获取id的值。

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

这就像是在说:“我想从对象myobject中获取属性id,但是如果这个对象里面没有id这个属性,那就返回None。”这样做既简单又高效。

有些对象还支持另一种形式的getattr访问:

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

根据提问者的要求,‘深层获取属性’

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)

撰写回答