In Python höre ich oft, dass es besser ist, "um Verzeihung zu bitten" (Ausnahmefang), als "um Erlaubnis zu bitten" (Typ- / Zustandsprüfung). In Bezug auf die Durchsetzung der Enten-Typisierung in Python ist dies
try:
x = foo.bar
except AttributeError:
pass
else:
do(x)
besser oder schlechter als
if hasattr(foo, "bar"):
do(foo.bar)
else:
pass
in Bezug auf Leistung, Lesbarkeit, "Python" oder einen anderen wichtigen Faktor?
exceptions
python
duck-typing
Darkfeline
quelle
quelle
hasattr
dass dies intern mit genau diesem Try / Catch umgesetzt wurde. Nicht sicher, ob es wahr ist ... (es würde anders auf Eigenschaften wirken, nicht wahr? Vielleicht denke ich angetattr
..)hasattr
verwendet das C-API-Äquivalent vongetattr
(return,True
wenn erfolgreich,False
wenn nicht), aber die Behandlung von Ausnahmen in C ist viel schneller.Antworten:
Es hängt wirklich davon ab, wie oft Sie denken, dass die Ausnahme ausgelöst wird.
Beide Ansätze sind meiner Meinung nach gleichermaßen gültig, zumindest in Bezug auf Lesbarkeit und Pythonität. Wenn jedoch 90% Ihrer Objekte nicht über das Attribut verfügen, stellen
bar
Sie einen deutlichen Leistungsunterschied zwischen den beiden Ansätzen fest:Aber wenn 90% der Objekte haben das Attribut haben, haben das Blatt gewendet worden:
Aus Sicht der Leistung müssen Sie also den Ansatz auswählen, der für Ihre Umstände am besten geeignet ist.
Am Ende kann eine strategische Verwendung des
timeit
Moduls das Pythonischste sein, was Sie tun können.quelle
hasattr
es tatsächlich das C-api-Äquivalent eines try-except unter der Haube gibt, da es sich als die einzige allgemeine Möglichkeit herausstellt, zu bestimmen, ob ein Objekt in Python ein Attribut hat, zu versuchen, darauf zuzugreifen.In Python erhalten Sie häufig eine bessere Leistung, wenn Sie Dinge auf die Python-Weise erledigen. In anderen Sprachen wird die Verwendung von Ausnahmen zur Flusskontrolle im Allgemeinen als schrecklich angesehen, da Ausnahmen normalerweise einen außerordentlichen Aufwand verursachen. Da diese Technik jedoch ausdrücklich in Python unterstützt wird, ist der Interpreter für diesen Codetyp optimiert.
Wie bei allen Leistungsfragen besteht die einzige Möglichkeit, sicher zu sein, darin, Ihren Code zu profilieren. Schreiben Sie beide Versionen und sehen Sie, welche schneller läuft. Meiner Erfahrung nach ist der "Python-Weg" in der Regel der schnellste Weg.
quelle
Die Leistung ist meines Erachtens ein zweitrangiges Anliegen. In diesem Fall hilft Ihnen ein Profiler dabei, sich auf die tatsächlichen Engpässe zu konzentrieren, die möglicherweise darin bestehen, wie Sie mit möglichen illegalen Argumenten umgehen.
Lesbarkeit und Einfachheit stehen dagegen immer im Vordergrund. Hier gibt es keine strengen Regeln, nutzen Sie einfach Ihr Urteilsvermögen.
Dies ist eine universelle Angelegenheit, aber umwelt- oder sprachspezifische Konventionen sind relevant. Zum Beispiel ist es in Python normalerweise in Ordnung, einfach das erwartete Attribut zu verwenden und einen möglichen AttributeError den Aufrufer erreichen zu lassen.
quelle
In Bezug auf die Korrektheit denke ich, dass die Ausnahmebehandlung der richtige Weg ist (manchmal benutze ich jedoch den hasattr () - Ansatz). Das Grundproblem bei der Verwendung von hasattr () besteht darin, dass Verstöße gegen Codeverträge in unbeaufsichtigte Fehler umgewandelt werden (dies ist ein großes Problem in JavaScript, bei dem nicht vorhandene Eigenschaften nicht berücksichtigt werden).
quelle