2012-12-29 8 views
7

Una domanda un po 'noobish e di buone pratiche. Ricerco dinamicamente i valori degli attributi degli oggetti usando object.__dict__[some_key] per abitudine. Ora mi chiedo quale sia meglio/più veloce: la mia attuale abitudine o getattr(object,some_key). Se uno è migliore, perché?getattr() rispetto alla ricerca dict, che è più veloce?

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

Perché non provare entrambi e vedere quale è più veloce? –

risposta

35

Tu sei molto meglio utilizzare getattr() invece di andare direttamente alla struttura __dict__.

Non

perché è più veloce o più lento, ma perché l'API ufficiale lavora in tutti circostanze, anche per le classi che fanno non avere un __dict__ (quando si utilizza __slots__ per esempio), o quando un oggetto implementa l'__getattr__ o __getattribute__ hook o quando l'attributo in questione è un descriptor (ad esempio property) o un attributo di classe.

Se vuoi sapere se qualsiasi dichiarazione un pitone o la tecnica è più veloce rispetto ad un altro, utilizzare il timeit module-misura la differenza:

>>> 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 

si può vedere che accedendo direttamente __dict__ è più veloce, ma getattr() fa molto più lavoro.

+1

+1 per aver menzionato '__slots__' e suggerendo la misurazione. –

+7

'getattr' rispetta anche l'MRO ei descrittori (esempio comune: proprietà). – delnan

+0

Non potrei chiedere una risposta migliore! Grazie – Cole