Wie überprüfe ich, ob ein Objekt ein Attribut hat?
Lesezeit: 8 Minuten
Lucas Gabriel Sanchez
Wie überprüfe ich, ob ein Objekt ein Attribut hat? Zum Beispiel:
>>> a = SomeClass()
>>> a.property
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'
Wie erkenne ich ob a hat das Attribut property bevor Sie es verwenden?
Wenn du sagst “Sagen Sie, ob a die Attribut-Eigenschaft hat, bevor Sie es verwenden?” Möchten Sie eine Funktion, die einen booleschen Wert zurückgibt (wie z hasattr() Returns) oder ist es in Ordnung, eine zu werfen AttributeError Ausnahme?
– smci
28. Februar um 4:04 Uhr
Benennen Sie Ihr Attribut auch nicht wirklich ‘property’ , weil Python es getan hat property Dekorateur und eingebaut auch, und diese unterscheiden sich geringfügig von normalen Attributen/Methoden.
Siehe die Antwort von Zweiterlinde unten, die gute Ratschläge zum Bitten um Vergebung gibt! Ein sehr pythonischer Ansatz!
Die allgemeine Praxis in Python ist, dass, wenn die Eigenschaft wahrscheinlich die meiste Zeit vorhanden ist, sie einfach aufgerufen wird und entweder die Ausnahme weitergegeben wird oder sie mit einem Try/Except-Block abgefangen wird. Dies wird wahrscheinlich schneller sein als hasattr. Wenn die Immobilie wahrscheinlich die meiste Zeit nicht vorhanden ist oder Sie sich nicht sicher sind, verwenden Sie hasattr wird wahrscheinlich schneller sein, als wiederholt in einen Ausnahmeblock zu fallen.
Scheint auch für die Suche nach Funktionen im Namensraum zu funktionieren, zB: import string hasattr(string, "lower")
– Riviera
8. April 2011 um 12:54 Uhr
hasattr ist genau das gleiche wie verwenden try/except AttributeError: Der Docstring von hasattr (in Python 2.7) sagt, dass er getattr Hand Catch Exceptions verwendet.
– Jeff Tratner
27. April 2012 um 3:04 Uhr
@ JeffTratner: hasattr ist leider nicht exakt das gleiche wie ein try: ... except AttributeError: in Python 2.x seit hasattr Wille alle Ausnahmen abfangen. In meiner Antwort finden Sie ein Beispiel und eine einfache Problemumgehung.
– Martin Geisler
24. April 2013 um 7:44 Uhr
hasattr funktioniert nicht, wenn Ihr Objekt ein ‘dict’ ist. Verwenden Sie in diesen Fällen die Operator- oder Haskey-Methode.
– AnandShiva
4. April 2021 um 12:13 Uhr
kann es für Attribute für getan werden self? wie if not hasattr(self, 'property') innerhalb der __init__() der Objekterstellung
– Alper
14. September 2021 um 3:51 Uhr
zweitelinde
Als Jarret Hardie antwortete: hasattr wird den Trick machen. Ich möchte jedoch hinzufügen, dass viele in der Python-Community eine Strategie empfehlen, die lautet: „Einfacher um Vergebung zu bitten als um Erlaubnis“ (EAFP) statt „Schauen, bevor du springst“ (LBYL). Siehe diese Referenzen:
if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff()
Aber wie überprüfen Sie, ob es die a.property war, die AttributeError verursacht hat, und nicht etwas in doStuff()? Anscheinend nicht. Ich denke, es ist wirklich einfacher, um Vergebung zu bitten, aber oft ist es auch falsch.
– jpalecek
14. April 2009 um 13:22 Uhr
EAFP scheint … verrückt. HasAttr telegraphiert zukünftigen Wartungsprogrammierern, dass Sie nach einem bestimmten Attribut suchen. Das Erhalten einer Ausnahme sagt zukünftigen Programmierern nichts und könnte jemanden in den Kaninchenbau führen.
– Ethan Heilmann
14. Oktober 2010 um 18:54 Uhr
@e5: Sie haben in diesem Fall einen guten Punkt, aber in vielen Fällen ist EAFP die einzig richtige Option. Wenn Sie beispielsweise die Existenz einer Datei überprüfen und sie dann öffnen, in der Erwartung, dass sie definitiv existieren wird, ist Ihr Code falsch: Die Datei kann zwischen der Überprüfung und der Verwendung gelöscht oder umbenannt werden. Dies wird als TOCTOU-Fehler (Time-Of-Check-To-Time-Of-Use) bezeichnet und kann neben Abstürzen auch eine Quelle für Sicherheitslücken sein.
– max
1. Juni 2011 um 13:08 Uhr
@EthanHeilman es ist nur verrückt, wenn die Quelle der Ausnahme mehrdeutig ist, was in den meisten Fällen mit gutem Design vermieden werden kann. Eine gut geschichtete Strukturierung der Logik innerhalb von try / except / finally sorgt im Allgemeinen für eine robustere (weniger fehleranfällige) Logik, als den Code mit präventiven if-Prüfungen für jeden Teil des verbrauchenden Codes zu verunreinigen. Macht Fehler auch sehr explizit und gibt konsumierenden Programmierern die Möglichkeit, direkt damit umzugehen.
– Peter M.Elias
2. Januar 2013 um 16:23 Uhr
Die meisten Beschwerden über Mehrdeutigkeiten hier sind einfach darauf zurückzuführen, dass der Beispielcode schlecht strukturiert ist. Das einzige, was in der try: sollte der versuchte Attributzugriff sein; es gibt keinen Grund, die Ausführung zu wickeln doStuff auch. Es gibt jedoch immer noch ein gewisses Potenzial für Mehrdeutigkeiten: if property eine berechnete Eigenschaft anstelle eines einfachen Attributs ist, könnte ihre Implementierung erhöhen AttributeError im Inneren. Das ist der Grund, warum in fast allen realen Situationen wie dieser getattr ist beiden vorzuziehen hasattr oder fangen AttributeError.
– Karl Meier
24. September 2013 um 20:21 Uhr
Karl Meier
Sie können verwenden hasattr() oder fangen AttributeErroraber wenn Sie wirklich nur den Wert des Attributs mit einem Standardwert haben möchten, wenn er nicht vorhanden ist, ist die beste Option einfach zu verwenden getattr():
getattr(a, 'property', 'default value')
Dies löst beide oben genannten Probleme: a) Die Mehrdeutigkeit der Quelle eines möglichen AttributeError, b) Beibehaltung des EAFP-Ansatzes.
– Peter M.Elias
2. Januar 2013 um 16:17 Uhr
Es sind auch 25 % der Codezeilen. Das muss doch die beste Lösung sein.
– Fatuhoku
24. September 2013 um 11:36 Uhr
Dies ist die beste Lösung, “wenn Sie wirklich nur den Wert des Attributs mit einem Standardwert wollen”. Obwohl ich glaube, dass viele Leute dies tatsächlich wollen, wenn sie sagen, dass sie feststellen möchten, ob ein Attribut vorhanden ist, hat das OP tatsächlich nach letzterem gefragt, daher ist es vernünftig, dass die direkten Antworten auf diese Frage (hasattr, AttributeError) höher aufgeführt werden .
– Karl Meier
1. Dezember 2015 um 5:48 Uhr
Für die Erwähnung von “Standardeigenschaft” positiv bewertet. Es gab Zeiten, in denen ich das gebraucht habe, aber es vergessen habe!
– Vexen Crabtree
24. Juni 2021 um 11:56 Uhr
Es ist viel besser als die akzeptierte Antwort wie für mich in den meisten Fällen, da hasattr normalerweise verwendet wird, um zu prüfen, ob attr vorhanden ist, und dann seinen Wert zu prüfen, um eine Ausnahme zu vermeiden, und dies hilft, den Wert direkt ohne „if hasattr and check value“ zu prüfen.
– Grju
9. Dezember um 9:55
Fledermaus
Ich denke, wonach du suchst hasattr. Ich würde jedoch so etwas empfehlen, wenn Sie erkennen möchten Python-Eigenschaften–
Laut pydoc ruft hasattr(obj, prop) einfach getattr(obj, prop) auf und fängt Ausnahmen ab. Es ist also genauso gültig, den Attributzugriff mit einer try-Anweisung zu umschließen und AttributeError abzufangen, wie vorher hasattr() zu verwenden.
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
Nun, hasattr eigentlich vielleicht optimiert. ZB mit Pypy.
– Odinho-Velmont
18. August 2011 um 17:37 Uhr
+1. Das ist sogar sicherer als zu verwenden hasattr Wenn SomeClass überschreibt __getattr__ seit hasattr werde fangen alle Ausnahmen in Python 2.x, nicht nur AttributeError wie Sie es erwarten würden. Dies wurde in Python 3.2 behoben – siehe meine andere Antwort für eine einfache Problemumgehung.
Der Benutzer @jpalecek hat es erwähnt: Wenn an AttributeError kommt drinnen vor doStuff()du bist verloren.
Vielleicht ist dieser Ansatz besser:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
Nun, hasattr eigentlich vielleicht optimiert. ZB mit Pypy.
– Odinho-Velmont
18. August 2011 um 17:37 Uhr
+1. Das ist sogar sicherer als zu verwenden hasattr Wenn SomeClass überschreibt __getattr__ seit hasattr werde fangen alle Ausnahmen in Python 2.x, nicht nur AttributeError wie Sie es erwarten würden. Dies wurde in Python 3.2 behoben – siehe meine andere Antwort für eine einfache Problemumgehung.
– Martin Geisler
24. April 2013 um 7:47 Uhr
BEARBEITEN: Dieser Ansatz hat ernsthafte Einschränkungen. Es sollte funktionieren, wenn das Objekt ein ist wiederholbar eines. Bitte überprüfen Sie die Kommentare unten.
Wenn Sie verwenden Python 3.6 oder höher wie ich gibt es eine bequeme Alternative, um zu überprüfen, ob ein Objekt ein bestimmtes Attribut hat:
if 'attr1' in obj1:
print("attr1 = {}".format(obj1["attr1"]))
Allerdings bin ich mir nicht sicher, was jetzt der beste Ansatz ist. verwenden hasattr()verwenden getattr() oder verwenden in. Kommentare sind willkommen.
in Das Schlüsselwort funktioniert zum Überprüfen von iterierbaren Typen. Zum Beispiel, 'foo' in None wirft den Fehler TypeError: argument of type 'NoneType' is not iterable. Die Lösung besteht darin, vor der Verwendung zu prüfen, ob der Typ iterierbar ist in. Nachdem Sie Grenzfälle wie nicht iterierbaren Typ korrigiert haben, sind Sie wahrscheinlich besser dran hasattr() weil es für Grenzfälle ausgelegt ist.
– Seth Difley
5. Oktober 2017 um 13:06 Uhr
Das hat nichts mit Attributzugriff zu tun. Ich habe keine Ahnung, wie es hochgestimmt wurde. Die einzige Ähnlichkeit, die es mit dem Attributzugriff hat, ist, ob Sie verwenden dict als “leichtgewichtiges Objekt”, ähnlich dem Design von JavaScript-Objekten, aber die meisten normalen Klassen unterstützen dies im Allgemeinen nicht (erhalten eine Variante des von @SethDifley erwähnten Fehlers).
– ShadowRanger
25. April 2018 um 19:37 Uhr
14367000cookie-checkWie überprüfe ich, ob ein Objekt ein Attribut hat?yes
Wenn du sagst “Sagen Sie, ob a die Attribut-Eigenschaft hat, bevor Sie es verwenden?” Möchten Sie eine Funktion, die einen booleschen Wert zurückgibt (wie z
hasattr()
Returns) oder ist es in Ordnung, eine zu werfenAttributeError
Ausnahme?– smci
28. Februar um 4:04 Uhr
Benennen Sie Ihr Attribut auch nicht wirklich ‘property’ , weil Python es getan hat
property
Dekorateur und eingebaut auch, und diese unterscheiden sich geringfügig von normalen Attributen/Methoden.– smci
28. Februar um 4:07 Uhr