attribute - python instance variables




Wie erkennt man, ob ein Objekt ein Attribut in Python hat? (6)

Gibt es eine Möglichkeit in Python festzustellen, ob ein Objekt ein Attribut hat? 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 können Sie feststellen, ob a die Attributeigenschaft hat, bevor Sie sie verwenden?


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

Hoffe, Sie erwarten hasattr (), aber versuchen Sie, hasattr () zu vermeiden und bevorzugen Sie bitte getattr (). getattr () ist schneller als hasattr ()

mit hasattr ():

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

Gleiches hier benutze ich getattr, um Eigenschaft zu erhalten, wenn es keine Eigenschaft gibt, die keine zurückbringt

   property = getattr(a,"property",None)
    if property:
        print property

Ich möchte vorschlagen, dies zu vermeiden:

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

Der Benutzer @jpalecek hat es erwähnt: Wenn innerhalb von doStuff() ein AttributeError auftritt, sind Sie verloren.

Vielleicht ist dieser Ansatz besser:

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

In Abhängigkeit von der Situation können Sie beispielsweise prüfen, welche Art von Objekt Sie haben, und dann die entsprechenden Attribute verwenden. Mit der Einführung von abstrakten Basisklassen in Python 2.6 / 3.0 ist dieser Ansatz auch viel mächtiger geworden (im Grunde erlaubt ABC eine differenziertere Art der Duck-Typisierung).

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. Wenn Sie nur hasattr kann dies zu seltsamen Fehlern führen.

Ein schönes Beispiel ist die Unterscheidung zwischen Iteratoren und Iterablen (siehe this Frage). Die __iter__ Methoden in einem Iterator und eine Iterable haben denselben Namen, sind aber semantisch ziemlich verschieden! So ist hasattr nutzlos, aber isinstance Zusammenarbeit mit ABC's bietet eine saubere Lösung.

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


Versuchen Sie hasattr() :

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

EDIT: Siehe weiter unten die Antwort von zweiterlinde , die einen guten Ratschlag zum Thema Vergebung gibt! 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 Eigenschaft wahrscheinlich die meiste Zeit nicht da ist oder Sie sich nicht sicher sind, wird die Verwendung von hasattr wahrscheinlich schneller sein, als wiederholt in einen Ausnahmeblock zu fallen.


Wie Jarret Hardie antwortete, wird hasattr 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()




attributes