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
异常类型并让任何其他异常引发未处理。
为什么 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 callinggetattr(object, name)
and seeing whether it raises anAttributeError
or not.)
修复是 here,但该更改未向后移植。
如果Python2行为给您带来麻烦,请考虑避免使用hasattr
;相反,您可以在 getattr
周围使用 try/except,仅捕获 AttributeError
异常类型并让任何其他异常引发未处理。