【问题标题】:Python's hasattr sometimes returns incorrect resultsPython 的 hasattr 有时会返回不正确的结果
【发布时间】:2016-06-04 15:34:36
【问题描述】:

为什么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 properties attributes python-2.x hasattr


    【解决方案1】:

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

    不幸的是,这意味着属性中任何未处理的异常都将被吞没,并且该代码中的错误可能会丢失。雪上加霜的是,当 hasattr 吃到异常时,它也会返回一个错误的答案(这里属性 a.foo 确实存在,所以结果应该返回 True 如果有的话)。

    在 python3.2+ 中,该行为已得到纠正:

    hasattr(object, name)

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

    修复是 here,但不幸的是,该更改没有向后移植。

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

    【讨论】:

    • 尽管引用了 Python 文档,hasattr 的行为仍可能被认为是奇怪的。确实,属性内的任意异常不再导致该属性被视为不存在(而是在调用者的脸上直接引发),但如果 AttributeError 源自属性内的某个位置,hasattr 的结果仍将是False。这可能不是故意的。 (或者它可能,所以一个属性可以确定它自己是否想要“在那里”。)无论如何,考虑到副作用等,执行该属性首先对我来说是错误的。
    • 实际上并没有一种直接的方法来确定 AttributeError 是由属性获取机制本身引发的,还是由属性中的代码引发的。
    猜你喜欢
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 2012-04-11
    • 2016-02-06
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多