2013-08-29 72 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:那里,更好? –