2012-03-20 12 views
10

Aşağıdaki örnek, Python 2.7'deki REST veritabanı sürücüsünden alınmıştır. Ben dışarı yorumladı getattr() hattını kullanıyorsanız aşağıda __setattr__ yöntemdeNeden getattr() öğesi, self .__ dict __. Get()?

, bu 230.

-600 rps'de nesne örnekleme performansı neden bu kadar yavaş bu durumda self.__dict__.get() daha getattr() olduğunu azaltır?

Kısacası
class Element(object): 

    def __init__(self, client): 
     self._client = client 
     self._data = {} 
     self._initialized = True 

    def __setattr__(self, key, value): 
     #_initialized = getattr(self, "_initialized", False) 
     _initialized = self.__dict__.get("_initialized", False) 
     if key in self.__dict__ or _initialized is False: 
      # set the attribute normally 
      object.__setattr__(self, key, value) 
     else: 
      # set the attribute as a data property 
      self._data[key] = value 
+1

Bir yan notda, böyle bir performans farkı yaşıyorsanız, yerel bir değişkende 'self .__ dict__' önbelleğini yapın - hatta yalnızca iki erişim için. ('__setattr__' başlangıcında (dict_ = self .__ dict__') – jsbueno

cevap

12

: tıpkı __dict__ özelliği erişme aynı şey değildir getattr(foo,bar)does the same thing as foo.bar, çünkü (bir başlangıç ​​için, getattr hakkı __dict__ seçmek zorundadır, ancak daha fazla oluyor bir sürü var).

Buraya iliştirilmiş veya buraya bağlı bilgiler: http://docs.python.org/reference/datamodel.html ("getattr" için arama).

+2

@bereal: Bir şeyleri tekrar okumanız gerekiyor. Foo .__ dict __. Get() için gerekli işlemler getattr() 'ın uygun bir alt kümesidir. – bukzor

+2

@bereal Python bayt kodlarının ilkel işlemlere karşılık gelmediğini unutmayın. Çok karmaşık bir işlevi çağırmak için çok az miktarda bytecode kullanabilirsiniz, tek bir basit ifade daha fazla bayt kodu oluşturabilir. Ayrıca, bukzor'un söylediği doğru ve alakalı. – Marcin

+0

@bereal Bu, 'foo .__ dict__'' nin getattr (foo, '__dict __') 'ile aynı anlama gelmediğini, çünkü 'getattr' (foo, '__ dict __')' 'nin daha verimli olması için çağıramaz. keyfi bir özniteliğin kaldırılması. – Marcin