Frage Wie erkennt man, ob ein Objekt ein Attribut in Python hat?


Gibt es eine Möglichkeit in Python festzustellen, ob ein Objekt ein Attribut besitzt? Beispielsweise:

>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'

Wie kannst du sagen, ob a hat das Attribut property bevor Sie es benutzen?


1137
2018-03-04 14:45


Ursprung


Antworten:


Versuchen hasattr():

if hasattr(a, 'property'):
    a.property

EDIT: Siehe zweiterlinde's Antwort Unten, wer bietet guten Ratschlag um Vergebung zu bitten! Ein sehr pythonischer Ansatz!

Die allgemeine Praxis in Python ist, dass, wenn die Eigenschaft wahrscheinlich die meiste Zeit da ist, sie einfach aufgerufen wird und entweder die Ausnahme propagieren lässt oder sie mit einem try / except-Block abfängt. Dies wird wahrscheinlich schneller sein als hasattr. Wenn die Unterkunft wahrscheinlich die meiste Zeit nicht da ist oder Sie sich nicht sicher sind, ob Sie sie nutzen hasattr wird wahrscheinlich schneller sein als wiederholt in einen Ausnahmeblock zu fallen.


1589
2018-03-04 14:48



Wie Jarret Hardie antwortete, hasattr wird den Trick machen. Ich möchte jedoch hinzufügen, dass viele in der Python-Community eine Strategie "leichter um Vergebung als Erlaubnis bitten" (EAFP) empfehlen, anstatt "vor dem Sprung zu schauen" (LBYL). Siehe diese Referenzen:

EAFP vs LBYL (war Re: Bis jetzt ein wenig enttäuscht)
EAFP vs. LBYL @Code Wie ein Pythonist: Idiomatische Python

zB:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

... wird bevorzugt zu:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

461
2018-03-04 14:56



Sie können verwenden hasattr() oder fangen AttributeError, aber wenn Sie wirklich nur den Wert des Attributs mit einem Standard haben möchten, wenn es nicht da ist, ist die beste Option nur zu verwenden getattr():

getattr(a, 'property', 'default value')

370
2018-03-04 17:54



Ich denke, wonach Sie suchen hasattr. Ich würde jedoch so etwas empfehlen, wenn Sie erkennen möchten Python-Eigenschaften-

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

Der Nachteil hierbei ist, dass Attributfehler in den Eigenschaften auftreten __get__ Code wird auch gefangen.

Sonst

if hasattr(someObject, 'someProp'):
    #Access someProp/ set someProp
    pass

Dokumente:http://docs.python.org/library/functions.html
Warnung:
Der Grund für meine Empfehlung ist, dass hasattr keine Eigenschaften erkennt.
Verknüpfung:http://mail.python.org/pipermail/python-dev/2005-December/058498.html


33
2018-03-04 14:52



Gemäß pydoc ruft hasattr (obj, prop) einfach getattr (obj, prop) auf und fängt Ausnahmen ab. Es ist also genauso wichtig, den Attributzugriff mit einer try-Anweisung zu umbrechen und AttributeError zu fangen, wie es zuvor für hasattr () verwendet wurde.

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

24
2018-03-04 14:56



Ich möchte vorschlagen, dies zu vermeiden:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

Der Benutzer @jpalecek hat es erwähnt: Wenn ein AttributeError tritt innen auf doStuff(), du bist verloren.

Vielleicht ist dieser Ansatz besser:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

13
2017-08-26 13:04



Abhängig von der Situation können Sie mit überprüfen isinstance Welche Art von Objekt haben Sie und verwenden Sie dann die entsprechenden Attribute. Mit der Einführung von abstrakte Basisklassen In Python 2.6 / 3.0 ist dieser Ansatz auch viel mächtiger geworden (im Grunde erlaubt ABCs eine differenziertere Art der Enteneingabe).

Eine Situation, in der dies nützlich wäre, wäre, wenn zwei verschiedene Objekte ein Attribut mit dem gleichen Namen aber unterschiedlicher Bedeutung hätten. Nur verwenden hasattr könnte dann zu seltsamen Fehlern führen.

Ein schönes Beispiel ist die Unterscheidung zwischen Iteratoren und Iterablen (vgl Dies Frage). Das __iter__ Methoden in einem Iterator und einem Iterablen haben denselben Namen, sind aber semantisch ziemlich verschieden! Damit hasattr ist nutzlos, aber isinstance zusammen mit ABC's bietet eine saubere Lösung.

Ich stimme jedoch zu, dass in den meisten Fällen die hasattr Ansatz (in anderen Antworten beschrieben) ist die am besten geeignete Lösung.


11
2018-03-04 15:41