Python hasattr vs getattr
Habe ich in letzter Zeit gelesen einige tweets und die python-Dokumentation über hasattr und er sagt:
hasattr(Objekt, name)
Die Argumente ein Objekt und ein string. Das Ergebnis ist True, wenn die Zeichenfolge ist der name >> einer der Objekt-Attribute, False, wenn nicht. (Dies erfolgt durch den Aufruf
getattr(object, name) und sehen, ob es löst einen AttributeError oder nicht.)
Es gibt ein motto in Python, der sagt, dass ist Einfacher um Vergebung zu bitten als Erlaubnis wo ich in der Regel Zustimmen.
Habe ich versucht zu tun, ein performance-test in diesem Fall mit einer wirklich einfachen python-code:
import timeit
definition="""\
class A(object):
a = 1
a = A()
"""
stm="""\
hasattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)
stm="""\
getattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)
Mit den Ergebnissen:
$ python test.py
hasattr(a, 'a')
1.26515984535
getattr(a, 'a')
1.32518696785
Ive versucht auch, was passiert, wenn das Attribut nicht existiert und die Unterschiede zwischen getattr und hasattr sind größer. Also, was Ich gesehen habe bisher ist, dass getattr ist langsamer als hasattr, aber in der Dokumentation heißt es, dass es Anrufe getattr.
Ive gesucht der CPython-Implementierung von hasattr und getattr und es scheint, dass beide Aufruf der nächsten Funktion:
v = PyObject_GetAttr(v, name);
aber es gibt noch mehr boilerplate in getattr als in hasattr, dass macht es wahrscheinlich langsamer.
Wer weiß, warum Sie in der Dokumentation, die wir sagen, dass hasattr Anrufe getattr und wir scheinen ermutigen die Nutzer, um getattr statt hasattr, wenn es wirklich nicht wegen der Leistung? Nur weil es mehr pythonic?
Vielleicht bin ich etwas falsch in meinem test 🙂
Dank,
Raúl
- Der Unterschied hier ist nicht Leistung. Du redest wie 5 Nanosekunden. Sie verlieren Tausende von Zeiten, die nur mit Hilfe von Python. Der Unterschied ist hier, welche ist die richtige für das, was Sie tun müssen.
- Der Leistungsunterschied war nicht der Punkt. Ich habe nicht verstanden, warum Sie den Kommentar in der Dokumentation, die besagt, dass es implementiert wurde, der Aufruf von getattr dort war.
- Vielleicht an einer Stelle es aufgerufen habe
getattr
, und jetzt ist es nicht, aber niemand aktualisiert, die docs...? Ehrlich gesagt, obwohl, das ist die Art von Aussage, die nicht gehören in der API-Dokumentation sowieso. Die Dokumente sollten erklären, was passiert, nicht wie es geschieht, es sei denn, das "wie" ist ein wesentlicher Teil des "was".
Du musst angemeldet sein, um einen Kommentar abzugeben.
In der Dokumentation nicht empfehlen, die Dokumentation nur Staaten das offensichtliche. Die
hasattr
ist implementiert als solche, und werfen einAttributeError
aus einer property get kann es so Aussehen wie das Attribut nicht vorhanden. Dies ist ein wichtiges detail, und das ist, warum es ist ausdrücklich in der Dokumentation. Betrachten Sie zum Beispiel diesen code:Das Ergebnis ist
Ist die
Spam
Klasse hat ein property descriptor füreggs
, aber da der getter wirftAttributeError
wennnot self.sausages
, dann wird die Instanz der Klasse nicht "hasattr
"eggs
.Andere als das, verwenden Sie
hasattr
nur, wenn Sie brauchen nicht den Wert; wenn Sie brauchen, der Wert, die Verwendunggetattr
mit 2 Argumenten und fangen Sie die Ausnahme, oder 3 Argumente, die Dritte einen sinnvollen default-Wert.Die Ergebnisse mit
getattr()
(2.7.9):Scheint, dass
hasattr
hat ein problem mit dem schlucken Ausnahmen (zumindest in Python 2.7), so ist wahrscheinlich besser, zu bleiben Weg von es bis es behoben ist.Nehmen, zum Beispiel, der folgende code: