Python 的 hasattr 有时 returns 不正确的结果

Python's hasattr sometimes returns incorrect results

为什么 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 的 Python 2 实现相当幼稚,它只是尝试访问该属性并查看它是否引发异常。

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

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

hasattr(object, name)

The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an AttributeError or not.)

修复是 here,但该更改未向后移植。

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