2011-09-17 70 views
2

這將導致一個無限遞歸循環時SETATTR被調用時,試圖設置some_prop的值,這與一個setter一個屬性時:如何避免使用__setattr__和屬性設置器的遞歸循環?

class TypeSystem(object): 

    def __setattr__(self, key, value): 
     if the_special_case is True: 
      # do something 
     else: 
      super(TypeSystem,self).__setattr__(key,value) 


class Entity(TypeSystem): 

    @property 
    def some_prop(self): 
     some_prop = self.data.get('some_prop') 
     if some_prop is None and hasattr(self,"some_prop"): 
      some_prop = self.some_prop 
     return some_prop 

    @some_prop.setter 
    def some_prop(self,value): 
     self.some_prop = value 

>>> entity = Entity() 
>>> entity.some_prop = 3 

這對於沒有定義爲屬性正常屬性工作正常因爲Super會調用對象的setattr來防止遞歸循環。

但是因爲some_prop沒有預先定義,它看起來像setattr被調用,而不是some_prop的設置器,所以它被拉到一個循環。

我已經嘗試了這個問題,以及....

@some_prop.setter 
def some_prop(self, value): 
    super(TypeSystem, self).__setattr__("some_prop", value) 

但它仍然進入一個遞歸循環。我沒有看到如何避免它。

回答

10

這與__setattr__TypeSystem無關。你的問題是

@some_prop.setter 
def some_prop(self,value): 
    self.some_prop = value 

這顯然是一個無限循環 - 你試圖在屬性的setter中設置屬性。

你有同樣的問題在吸氣:

some_prop = self.some_prop 

會導致無限循環,以及 - 你試圖獲得屬性的getter的屬性。

您需要使用另一個變量來保存當前數據:

class Entity(TypeSystem): 

    @property 
    def some_prop(self): 
     some_prop = self.data.get('some_prop') 
     if some_prop is None and hasattr(self,"_some_prop"): 
      some_prop = self._some_prop 
     return some_prop 

    @some_prop.setter 
    def some_prop(self,value): 
     self._some_prop = value