为什么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
说实例没有foo
属性?
>>> class A(object):
... @property
... def foo(self):
... ErrorErrorError
...
>>> a = A()
>>> hasattr(a, 'foo')
False
我期望:
>>> hasattr(a, 'foo')
NameError: name 'ErrorErrorError' is not defined`
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