getattr() по сравнению с поиском в dict, что быстрее?

Несколько нубский вопрос о лучшей практике. Я динамически ищу значения атрибутов объекта, используя object.__dict__[some_key] по привычке. Теперь мне интересно, что лучше/быстрее: моя текущая привычка или getattr(object,some_key). Если один лучше, то почему?

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

person Cole    schedule 29.12.2012    source источник
comment
Почему бы не попробовать оба и посмотреть, что быстрее?   -  person Michael Mior    schedule 29.12.2012


Ответы (1)


Гораздо лучше использовать getattr() вместо того, чтобы обращаться непосредственно к структуре __dict__.

Не потому, что он быстрее или медленнее, а потому, что официальный API работает в всех обстоятельствах, в том числе для классов, у которых нет __dict__ (при использовании __slots__, например), или когда объект реализует __getattr__ или __getattribute__ или когда рассматриваемый атрибут является дескриптор (например, property ) или атрибут класса.

Если вы хотите узнать, работает ли какой-либо один оператор или метод Python быстрее другого, используйте модуль timeit. чтобы измерить разницу:

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

Вы можете видеть, что прямой доступ к __dict__ выполняется быстрее, но getattr() выполняет гораздо больше работы.

person Martijn Pieters    schedule 29.12.2012
comment
getattr также учитывает MRO и дескрипторы (общий пример: свойства). - person ; 29.12.2012
comment
Я не мог просить лучшего ответа! Спасибо - person Cole; 29.12.2012