Exceptions statt hasattr(), has_key(), etc. (was: Elemente in Liste gruppieren und zählen)

19/04/2008 - 10:32 von Volker Grabsch | Report spam
Michael Ströder <michael@stroeder.com> schrieb:

Berthold Höllmann wrote:

Michael Ströder <michael@stroeder.com> writes:


BTW: has_key() und setdefault() sind u.U. mit eben jenem
try-except-Block implementiert.



Ein Implementierungsdetail, dass sich àndern kann. :-)



Eher unwahrscheinlich. Es wird auch meist dazu geraten, nicht hasattr()
zu verwenden, sondern

try:
value = getattr(...)
except AttributeError:
value = .. # irgendwas sinnvolles



Bei hasattr() geht es darum, dass man

nicht:

if hasattr(x, 'myattr'):
value = x.myattr
else:
value = None

sondern:

try:
value = x.myattr
except AttributeError:
value = None

schreiben sollte. Übertràgt man das auf Dictionaries, bedeutet
es, dass man

nicht:

if d.has_key('mykey'):
value = d['mykey']
else:
value = None

sondern:

try:
value = d['mykey']
except KeyError:
value = None

schreiben sollte. Hintergrund ist einerseits, dass die try/except-
Varianten einfacher sind, und ohne doppelte Nennung des Attribut-
bzw. Key-Namens auskommen, also weniger fehleranfàllig sind.

Wichtiger ist aber, dass man die Fehler-Erkennung grundsàtzlich der
aufgerufenen Funktion überlassen sollte, und nur die Fehler-Behandlung
selbst vornimmt. Das fàllt bei einfachen Dictionaries und Objekt-
Attributen nicht auf, aber spàtestens bei "mkdir()" und Konsorten
wird es offensichtlich: Es gibt so viele Gründe, aus denen das schief
gehen kann, die /will/ man gar nicht vorher prüfen. (Readonly-Dateisystem,
Rechte, ACLs, Verzeichnis schon vorhanden, ...)

Zudem kann es passieren, dass zwischen Überprüfung und Funktionsaufruf
sich die Situation àndert. Gut, das Dictionary müsste dazu von einem
anderen Thread manipuliert werden, aber z.B. bei "mkdir()" wàre das
eine ernsthafte Gefahr.

All diese Argumente sprechen dafür, die Fehler-Erkennung den
entsprechenden Funktionen anzuvertrauen. Und /deshalb/ wird von
has_key(), hasattr() & Co. abgeraten.


Gruß,

Volker

"Wenn du der Meinung bist, der andere sei ein Depp, dann überlass das
Antworten denjenigen, die nicht dieser Meinung sind."

 

Lesen sie die antworten

#1 Peter Otten
19/04/2008 - 12:29 | Warnen spam
Volker Grabsch wrote:

Michael Ströder schrieb:
Berthold Höllmann wrote:
Michael Ströder writes:

BTW: has_key() und setdefault() sind u.U. mit eben jenem
try-except-Block implementiert.



Ein Implementierungsdetail, dass sich àndern kann. :-)



Eher unwahrscheinlich. Es wird auch meist dazu geraten, nicht hasattr()
zu verwenden, sondern

try:
value = getattr(...)
except AttributeError:
value = .. # irgendwas sinnvolles



Bei hasattr() geht es darum, dass man

nicht:

if hasattr(x, 'myattr'):
value = x.myattr
else:
value = None

sondern:

try:
value = x.myattr
except AttributeError:
value = None

schreiben sollte.



Es gibt auch noch getattr(x, "myattr", None); allerdings verwende auch ich
meist die try...except-Variante, weil ich finde, dass dabei myattr leichter
als Bezeichner zu erkennen ist. Dieses Argument entfàllt bei dictionaries,
wo die Situation etwas komplexer ist.

Übertràgt man das auf Dictionaries, bedeutet
es, dass man

nicht:

if d.has_key('mykey'):
value = d['mykey']
else:
value = None

sondern:

try:
value = d['mykey']
except KeyError:
value = None

schreiben sollte. Hintergrund ist einerseits, dass die try/except-
Varianten einfacher sind, und ohne doppelte Nennung des Attribut-
bzw. Key-Namens auskommen, also weniger fehleranfàllig sind.

Wichtiger ist aber, dass man die Fehler-Erkennung grundsàtzlich der
aufgerufenen Funktion überlassen sollte, und nur die Fehler-Behandlung
selbst vornimmt. Das fàllt bei einfachen Dictionaries und Objekt-



Das geht auch mit

value = d.get(key, default)

wenn der Vorgabewert eine Konstante ist. Hauptsàchlich aus
Performancegründen bietet sich

# nicht thread-safe
if key in d:
value = d[key]
else:
value = ...

an, wenn der Schlüssel "hàufig"* nicht gefunden wird.

Peter

(*) Hàufig heißt für CPython 2.5 laut meiner Messung mit Integer-Schlüsseln
in mehr als etwa 3 Prozent der Fàlle.

Ähnliche fragen