2012-12-29 17 views
7

Nieco nieobyczajne pytanie dotyczące najlepszej praktyki. Dynamicznie wyszukuję wartości atrybutów obiektów, używając jako przyzwyczajenia object.__dict__[some_key]. Teraz zastanawiam się, który jest lepszy/szybszy: mój obecny nawyk lub getattr(object,some_key). Jeśli jeden jest lepszy, dlaczego?getattr() versus dict lookup, który jest szybszy?

>>> class SomeObject: 
...  pass 
... 
>>> so = SomeObject() 
>>> so.name = 'an_object' 
>>> getattr(so,'name') 
'an_object' 
>>> so.__dict__['name'] 
'an_object' 
+0

Dlaczego nie spróbować obu i zobaczyć, który jest szybszy? –

Odpowiedz

35

Jesteś znacznie lepiej wyłączyć za pomocą getattr() zamiast iść bezpośrednio do konstrukcji __dict__.

Nie dlatego, że to szybciej lub wolniej, ale dlatego, że oficjalny API działa w wszystkich okoliczności, w tym dla klas, które wykonują nie mają __dict__ (przy użyciu __slots__ na przykład), lub gdy obiekt implementuje __getattr__ lub __getattribute__ haki lub gdy dany atrybut to descriptor (taki jak property) lub atrybut klasy.

Jeśli chcesz wiedzieć, czy jakiekolwiek stwierdzenie jeden pyton lub technika jest szybszy niż inne, należy użyć timeit module do miarą różnicę:

>>> import timeit 
>>> class Foo(object): 
...  pass 
... 
>>> foo = Foo() 
>>> foo.bar = 'spam' 
>>> timeit.timeit("getattr(foo, 'bar')", 'from __main__ import foo') 
0.2125859260559082 
>>> timeit.timeit("foo.__dict__['bar']", 'from __main__ import foo') 
0.1328279972076416 

Widać, że bezpośredni dostęp __dict__ jest szybsza, ale getattr() robi o wiele więcej pracy.

+1

+1 za podanie "__slots__" i sugerowanie pomiaru. –

+7

'getattr' również respektuje MRO i deskryptory (typowy przykład: właściwości). – delnan

+0

Nie mogłem poprosić o lepszą odpowiedź! Dzięki – Cole

Powiązane problemy