2011-03-19 58 views
2

這是我的代碼:__setattr__在這個python代碼中做了什麼?

class fun: 

    def __getattr__(self,key): 
     return self[key] 

    def __setattr__(self,key,value): 
     self[key] = value+1 
a = fun() 
a['x']=1 
print a['x'] 

和錯誤是:

AttributeError: fun instance has no attribute '__getitem__' 

當我將其更改爲:

class fun: 

    def __getattr__(self,key): 
     return self.key 

    def __setattr__(self,key,value): 
     self.key = value+1 
a = fun() 
a.x=1 
print a.x 

的錯誤是:

RuntimeError: maximum recursion depth exceeded 

我能做什麼, 我想得到2

回答

7

問題是,self.key = ...調用__setattr__,所以你最終在一個無限的遞歸。要使用__setattr__,您必須以其他方式訪問對象的字段。有兩種常見的解決方案:

def __setattr__(self,key,value): 
    # Access the object's fields through the special __dict__ field 
    self.__dict__[key] = value+1 

# or... 

def __init__(self): 
    # Assign a dict field to access fields set via __[gs]etattr__ 
    self.attrs = {} 

def __setattr__(self,key,value): 
    self.attrs[key] = value+1 
3

這是一個錯字。

你想要實施特殊方法__setattr__,而不是__serattr__這沒有什麼特別的意義。

+0

對不起,請參閱更新 – zjm1126 2011-03-19 09:42:36

1

首先,該方法被稱爲__setattr__()。這是當一個屬性分配嘗試。比如當你這樣做的時候:

self[key] = value+1 

......使你的特殊呼叫(無限)遞歸!

一個更好的方式來做到這將是從object派生類,所謂的new-style class和調用基類:

class fun(object): 

    def __setattr__(self,key,value): 
     super(fun, self).__setattr__(key, value + 1) 

a = fun() 
a.x=1 
print a.x 

我刪除了你的__getattr__()實現,因爲它並沒有任何價值。