为什么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`

最佳答案

hasattr的python2实现非常幼稚,它只是尝试访问该属性,并查看它是否引发异常。
不幸的是,这意味着属性中任何未处理的异常都将被吞没,并且该代码中的错误可能会丢失。更糟的是,当hasattr吞噬异常时,它还会返回错误的答案(此处a.foo属性确实存在,因此结果应返回True(如果有的话))。
在python3.2 +中,该行为已得到纠正:

解决方法是here,但不幸的是,该更改并没有反向移植。
如果python2行为给您带来麻烦,请考虑避免使用hasattr;相反,您可以在 getattr 周围使用try/except,仅捕获AttributeError异常,然后让其他任何未处理的异常引发。

10-06 13:48