96 Stimmen

hasattr() vs. try-except-Block zur Behandlung nicht vorhandener Attribute

if hasattr(obj, 'attribute'):
    # do somthing

gegen

try:
    # access obj.attribute
except AttributeError, e:
    # deal with AttributeError

Welche sollte bevorzugt werden und warum?

1 Stimmen

5voto

UncleZeiv Punkte 17632

Wenn das Attribut nicht vorhanden ist no eine Fehlerbedingung, hat die Variante der Ausnahmebehandlung ein Problem: Sie würde auch AttributeErrors abfangen, die möglicherweise intern beim Zugriff auf obj.attribute (z.B. weil attribute eine Eigenschaft ist, so dass der Zugriff darauf einen Code aufruft).

0 Stimmen

Dies ist ein großes Problem, das meiner Meinung nach weitgehend ignoriert wurde.

5voto

jxramos Punkte 6062

Dieses Thema wurde in dem EuroPython 2016 Vortrag behandelt Schnelleres Python schreiben von Sebastian Witowski. Hier ist eine Reproduktion seiner Folie mit der Zusammenfassung der Leistung. Er verwendet auch die Terminologie Vorsicht vor dem Sprung in dieser Diskussion, die es wert ist, hier erwähnt zu werden, um dieses Stichwort zu markieren.

Wenn das Attribut tatsächlich fehlt, wird das Bitten um Vergebung langsamer sein als um Erlaubnis zu bitten. Als Faustregel können Sie also um Erlaubnis bitten, wenn Sie wissen, dass das Attribut sehr wahrscheinlich Attribut fehlen wird oder andere Probleme, die Sie vorhersagen können. Andernfalls, wenn Sie erwarten, dass der Code in den meisten Fällen lesbar sein wird Code

3 ERLAUBNIS ODER VERGEBUNG?

# CASE 1 -- Attribute Exists
class Foo(object):
    hello = 'world'
foo = Foo()

if hasatter(foo, 'hello'):
    foo.hello
## 149ns ##

try:
    foo.hello
except AttributeError:
    pass
## 43.1 ns ##
## 3.5 times faster

# CASE 2 -- Attribute Absent
class Bar(object):
    pass
bar = Bar()

if hasattr(bar, 'hello'):
    bar.hello
## 428 ns ##

try:
    bar.hello
except AttributeError :
    pass
## 536 ns ##
## 25% slower

4voto

n8gray Punkte 4939

Wenn Sie nur ein einziges Attribut testen wollen, würde ich sagen, verwenden Sie hasattr . Wenn Sie jedoch mehrere Zugriffe auf Attribute, die möglicherweise nicht existieren, dann mit einer try Block kann Ihnen einige Tipparbeit ersparen.

3voto

Douglas Leeder Punkte 50423

Ich würde Option 2 vorschlagen. Option 1 hat eine Race Condition, wenn ein anderer Thread das Attribut hinzufügt oder entfernt.

Auch Python hat eine Idiom dass EAFP ('leichter um Vergebung zu bitten als um Erlaubnis') besser ist als LBYL ('schau, bevor du springst').

2voto

cjs Punkte 23476

Aus praktischer Sicht ist die Verwendung einer Bedingung in den meisten Sprachen immer deutlich schneller als die Behandlung einer Ausnahme.

Wenn Sie den Fall behandeln wollen, dass ein Attribut außerhalb der aktuellen Funktion nicht vorhanden ist, ist die Ausnahme der bessere Weg zu gehen. Ein Indikator dafür, dass Sie eine Ausnahme anstelle einer Bedingung verwenden sollten, ist die Tatsache, dass die Bedingung lediglich ein Flag setzt und die aktuelle Operation abbricht, während an anderer Stelle dieses Flag überprüft und darauf basierend Maßnahmen ergriffen werden.

Wie Rax Olgud hervorhebt, ist die Kommunikation mit anderen eine wichtige Eigenschaft des Codes, und es ist vielleicht wichtiger, was Sie sagen wollen, wenn Sie sagen: "Dies ist eine Ausnahmesituation" statt "Das ist etwas, das ich erwarte".

0 Stimmen

+1 für das Beharren auf der Tatsache, dass "versuchen" als "dies ist eine Ausnahmesituation" interpretiert werden kann, im Vergleich zum bedingten Test :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X