2013-07-22 63 views
1

我試圖實現一個簡單的模型類,該類在類中設置屬性時執行回調,但是在嘗試在我的應用程序中使用此屬性時出現AttributeError。看起來這個實例沒有我在初始化程序中設置的屬性,我爲什麼會有點困惑。我沒有用魔術方法很多,所以一些闡述可能會有所幫助:Python模型回調

class ReportModel(object): 

    def __init__(self): 
     self.current_date = None 
     self.prior_date = None 
     self._callbacks = defaultdict([]) 

    def __setattr__(self, attr, value): 
     object.__setattr__(self, attr, value) 
     for func in self._callbacks[attr]: 
      func(value) 

    def set_callback(self, attr, function): 
     self._callbacks[attr].append(function) 

回溯:

AttributeError: 'ReportModel' object has no attribute '_callbacks' 

回答

2

既然你已經覆蓋__setattr__(),當你在做__init__()self.current_date = None會打電話給你__setattr__()實現,這將嘗試訪問self._callbacks。這是導致AttributeError的原因。

這裏是一個選項,以解決此問題:

class ReportModel(object): 

    def __init__(self): 
     object.__setattr__(self, '_callbacks', defaultdict(list)) 
     self.current_date = None 
     self.prior_date = None 

    def __setattr__(self, attr, value): 
     object.__setattr__(self, attr, value) 
     for func in self._callbacks[attr]: 
      func(value) 

    def set_callback(self, attr, function): 
     self._callbacks[attr].append(function) 

這增加了使用object.__setattr__()添加任何其他屬性之前_callbacks屬性,讓你的ReportModel實例__setattr__()未來的呼叫將不會在訪問self._callbacks窒息。

或者,你可以修改__setattr__()來檢查_callbacks屬性的存在:

class ReportModel(object): 

    def __init__(self): 
     object.__setattr__(self, '_callbacks', defaultdict(list)) 
     self.current_date = None 
     self.prior_date = None 

    def __setattr__(self, attr, value): 
     object.__setattr__(self, attr, value) 
     if hasattr(self, '_callbacks'): 
      for func in self._callbacks[attr]: 
       func(value) 

    def set_callback(self, attr, function): 
     self._callbacks[attr].append(function) 
+0

想你的落實,我得到一個類型錯誤:文件「C:\ FAST \工作區\ FIMOApp \ SRC \ fimoapp \ models.py「,第12行,在__init__ object .__ setattr __(self,'_callbacks',defaultdict([])) TypeError:第一個參數必須可調用 – donopj2

+0

Woops - 它的defaultdict, – donopj2

2

__init__運行和設置self.current_dateself.prior_date__setattr__方法類的實例化過程中調用。

要解決這個問題,你必須使用try,除了阻止回調調用以防止錯誤。

try: 
     for func in self._callbacks[attr]: 
      func(value) 
    except: 
     pass