2012-02-14 31 views
5

Nesne özniteliklerinin tembel yükünü nasıl uygularsınız, ör. Özniteliklere erişilip henüz ulaşılamıyorsa, bunları yüklemesi gereken bazı nesne yöntemi çağrılır mı?Özniteliklerin yüklemesi

Benim ilk girişimi Belirli özellik adları yalnızca lazyload belirli yapacak

def lazyload(cls): 
    def _getattr(obj, attr): 
     if "_loaded" not in obj.__dict__: 
      obj._loaded=True 
      try: 
       obj.load() 
      except Exception as e: 
       raise Exception("Load method failed when trying to access attribute '{}' of object\n{}".format(attr, e)) 
      if attr not in obj.__dict__: 
       AttributeError("No attribute '{}' in '{}' (after loading)".format(attr, type(obj))) # TODO: infinite recursion if obj fails 
      return getattr(obj, attr) 
     else: 
      raise AttributeError("No attribute '{}' in '{}' (already loaded)".format(attr, type(obj))) 

    cls.__getattr__=_getattr 
    return cls 

@lazyload 
class Test: 
    def load(self): 
     self.x=1 

t=Test()  # not loaded yet 
print(t.x) # will load as x isnt known yet 

olduğunu. Henüz meta-sınıflandırma yapmadığım için, bu doğru yaklaşım olup olmadığından emin değilim. Ne önerirsiniz?

+1

* "metaclasses sen onlara ihtiyaç olup olmadığını merak varsa dert hiç gerektiğini kullanıcıların daha derin sihirli% 99'undan olan, bilmiyorsun.. " - TP *. Bence Daniel'ın önerdiği gibi bir mülk daha iyi olurdu. –

+0

Bu tarifi kullanıyorum http://code.activestate.com/recipes/576563-cached-property/ – reclosedev

+0

@Rik: Meta sınıflarına ihtiyacım olup olmadığını değil, tembel yük sorununu nasıl çözeceğimi düşünmüyorum. Daniels örneği henüz tam olarak çözülmez, çünkü salt okunurdur ve her oluşum için yinelenen kod satırları istemiyorum. Bu ayarlanabilir mi? – Gerenuk

cevap

6

basit property hile daha iyi yapacağını gibi görünüyor:

@property 
def my_attribute(): 
    if not hasattr(self, '_my_attribute'): 
     do_expensive_operation_to_get_attribute() 
    return self._my_attribute 
+1

Sesler düzgün, ama şimdi soru uygun hale getirilebilir mi? Yazılabilir özelliklere de ihtiyacım var. Ve daha da önemlisi, bunu aynı 4 satırı bir çok kez tekrar yazmadan güzel bir nota ekleyebilir miyim? – Gerenuk

+0

Sınıf tanımında veya benzer bir şeyde "my_attribute = lazyload (load_method)" yazabilir miyim? – Gerenuk