2013-08-29 67 views
1

我花了一些時間來學習Python的屬性魔法。但是,當我寫一個簡單的案例時會出現一個小錯誤,我會得到一個奇怪的結果。這裏是我的代碼:使用python屬性的奇怪結果

class PropertyShow(object): 
    def __init__(self): 
     self.__num = 90 

    def setNum(self,value): 
     self.__num = value 

    def getNum(self): 
     return self.__num 

    def delNum(self): 
     del self.__num 

    #num = property(getNum,setNum,delNum) 
    # I made a mistake here! 
    __num = property(getNum,setNum,delNum) 


class PropertyTwo(object): 
    def __init__(self): 
     self.__num = None 

    @property 
    def num(self): 
     """OK, use a decorator, you can do something here!""" 
     return self.__num 

    @num.setter 
    def num(self,value): 
     self.__num = value 

    @num.deleter 
    def num(self): 
     del self.__num 

one = PropertyShow() 
print one.num 
two = PropertyTwo() 
print two.num 

在重點線, 「NUM =屬性(getNum,setNum,delNum)」。我改變了這種粗心,現在就像這樣「__num = property(getNum,setNum,delNum)」。

這段代碼的結果是:

File "property.py", line 6, in setNum 
    self.__num = value 
RuntimeError: maximum recursion depth exceeded 
  1. 更換num__num時,爲什麼我得到這個意外的結果?
  2. 如何理解的property()魔術和爲什麼要使用私有變量?*

回答

4

self.__num = value導致屬性setter被調用。

屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。屬性設置器嘗試設置self.__num,這會導致調用屬性設置器。

檢測到無限遞歸。

當你的財產是不是名爲__num,這顯然不會發生。

要明確:Python看到行self.__num = value作爲STORE_ATTR操作碼:

>>> import dis 
>>> def setNum(self, value): 
...  self.__num = value 
... 
>>> dis.dis(setNum) 
    2   0 LOAD_FAST    1 (value) 
       3 LOAD_FAST    0 (self) 
       6 STORE_ATTR    0 (__num) 
       9 LOAD_CONST    0 (None) 
      12 RETURN_VALUE   

STORE_ATTR實施將首先尋找在類數據描述符,發現你的__numproperty對象。該呼叫然後有效地轉換爲:

PropertyShow.__num.__set__(self, value) 

property對象中查找配置setter函數,這是PropertyShow.setNum,並稱其爲PropertyShow.setNum(self, value)。這再次調用self.__num = value並且遞歸從那裏接管。

+0

那麼當屬性設置器試圖再次設置「self .__ num'時會發生什麼? –

+0

@JonClements:那裏,更好? –