6

为什么hasattr说实例没有foo属性?

>>> class A(object):
...     @property
...     def foo(self):
...         ErrorErrorError
... 
>>> a = A()
>>> hasattr(a, 'foo')
False

我期望:

>>> hasattr(a, 'foo')
NameError: name 'ErrorErrorError' is not defined`
4

1 回答 1

14

Python 2 的实现hasattr相当幼稚,它只是尝试访问该属性并查看它是否引发异常。

不幸的是,hasattr它将吃掉任何异常类型,而不仅仅是AttributeError匹配试图访问的属性的名称。它在所示示例中捕获了 a NameError,这导致在False此处返回不正确的结果。雪上加霜的是,属性中任何未处理的异常都会被吞没,属性代码中的错误可能会丢失,从而掩盖错误。

在 Python 3.2+ 中,该行为已得到纠正:

hasattr(object, name)

参数是一个对象和一个字符串。结果是True字符串是否是对象属性之一的名称,False如果不是。(这是通过调用getattr(object, name)并查看它是否引发 an来实现的AttributeError。)

修复程序在这里,但该更改没有被反向移植。

如果 Python 2 的行为给您带来麻烦,请考虑避免使用hasattr; 相反,您可以使用 try/except around ,getattr捕获异常类型并让任何其他异常引发未处理。AttributeError

于 2016-02-23T00:37:21.067 回答