2016-02-23 14 views
5

Warum sagt hasattr, dass die Instanz kein foo Attribut hat?Pythons HASATTR gibt manchmal falsche Ergebnisse zurück

>>> class A(object): 
...  @property 
...  def foo(self): 
...   ErrorErrorError 
... 
>>> a = A() 
>>> hasattr(a, 'foo') 
False 

ich erwartet hatte:

>>> hasattr(a, 'foo') 
NameError: name 'ErrorErrorError' is not defined` 

Antwort

11

Die python2 Implementierung von hasattr ziemlich naiv ist, es versucht, nur das Attribut zugreifen und sehen, ob es eine Ausnahme oder nicht erhöht.

Leider bedeutet dies, dass alle nicht behandelten Ausnahmen in den Eigenschaften verschluckt werden und Fehler in diesem Code verloren gehen können. Um eine Verletzung hinzuzufügen, wenn hasattr die Ausnahme isst, gibt es auch eine falsche Antwort zurück (hier existiert das Attribut a.fooexistiert, so sollte das Ergebnis True wenn überhaupt zurückgegeben haben).

In python3.2 +, hat sich das Verhalten korrigiert:

hasattr(object, name)

Die Argumente sind ein Objekt und eine Zeichenfolge. Das Ergebnis ist True, wenn die Zeichenfolge der Name eines der Attribute des Objekts ist, False wenn nicht. (Dies wird durch getattr(object, name) Aufruf implementiert und zu sehen, ob es ein AttributeError oder nicht erhöht.)

Das Update ist here, aber leider, dass Veränderungen zurückzuportieren nicht.

Wenn das Python2-Verhalten Probleme für Sie verursacht, sollten Sie die Verwendung von hasattr vermeiden; Stattdessen können Sie einen Versuch/Ausnahme um getattr verwenden, nur die AttributeError Ausnahme abfangen und alle anderen unbehandelt erhöhen lassen.

+4

Das Zitat aus der Python-Dokumentation trotz, 'hasattr'-Verhalten kann immer noch als seltsam angesehen werden. Es ist wahr, dass willkürliche Ausnahmen innerhalb einer Eigenschaft nicht mehr dazu führen, dass das Attribut als abwesend angesehen wird (sondern direkt im Gesicht des Aufrufenden ausgelöst wird), aber wenn ein Attributfehler von irgendwo innerhalb der Eigenschaft stammt, wird das Ergebnis von hasattr weiterhin angezeigt sei 'falsch'. Dies ist möglicherweise nicht beabsichtigt. (Oder, so kann eine Eigenschaft selbst bestimmen, ob sie "da" sein will.) In jedem Fall klingt die Ausführung der Eigenschaft in erster Linie falsch, unter Berücksichtigung von Nebenwirkungen usw. –

+0

Es gibt nicht wirklich einen direkten Weg um zu bestimmen, ob ein "AttributeError" durch die Attribut-erhaltende Maschine selbst oder durch den Code in einer Eigenschaft ausgelöst wurde. – kindall

Verwandte Themen