6

インスタンスに属性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`
4

1 に答える 1

14

の Python 2 実装hasattrはかなり素朴で、その属性にアクセスして、例外が発生するかどうかを確認するだけです。

残念ながら、アクセスしようとした属性の名前に一致するhasattrだけでなく、あらゆる例外タイプを食べます。AttributeError示されている例でa をキャッチしたNameErrorため、誤った結果Falseが返されます。さらに厄介なことに、プロパティ内の未処理の例外が飲み込まれ、プロパティ コード内のエラーが失われ、バグが隠されます。

Python 3.2+ では、動作が修正されました。

hasattr(object, name)

引数はオブジェクトと文字列です。結果はTrue、文字列がオブジェクトの属性の 1 つの名前である場合、Falseそうでない場合です。(これは、呼び出しgetattr(object, name)て an が発生するかどうかを確認することで実装されAttributeErrorます。)

修正はこちらにありますが、その変更はバックポートされませんでした。

Python 2 の動作が問題を引き起こす場合は、使用を避けることを検討してくださいhasattr。代わりに、 try/except around を使用して、例外タイプのみgetattrをキャッチし、他の例外を未処理のままにすることができます。AttributeError

于 2016-02-23T00:37:21.067 に答える