“属性”应用于实例变量“self.x”时“超出最大递归深度”

时间:2013-02-07 10:46:46

标签: python

我正在读取property(),我理解属性访问是通过property()中指定的方法完成的。 但是,当执行以下代码时,我得到“RuntimeError:超出最大递归深度”。

class Property(object):

    def __init__(self):
        self.x = "Raj"

    def gettx(self):
        print "getting x"
        return self.x

    def settx(self, val):
        print "Setting x"
        self.x = val

    def dellx(self):
        print "deleting"
        return self.x

    x = property(gettx, settx, dellx, "I'm object property")


p = Property()
print "p.x", p.x
p.x = "R"
print "p.x:", p.x

是否无法以这种方式申请财产。因为当'self.x'改为self._x和self .__ x时,它工作正常。

2 个答案:

答案 0 :(得分:11)

错误是由于以下无限递归循环:您已使用xgettxsettx访问方法定义了属性deltx,但访问权限方法本身尝试访问属性x(即自称)。

您应该按以下方式编写代码:

class Property(object):

    def __init__(self):
        self.__x = "Raj"  # Class private

    def gettx(self):
        print "getting x"
        return self.__x

    def settx(self, val):
        print "Setting x"
        self.__x = val

    def dellx(self):
        print "deleting"
        return self.__x

    x = property(gettx, settx, dellx, "I'm object property")

答案 1 :(得分:0)

根据python docs

  

如果c是C的实例,c.x将调用getter,c.x = value将   调用setter和del c.x删除器。

因此,您的代码行self.x = "Raj"实质上会调用方法settx(self, val)。在该方法中,行self.x = val再次调用settx(self, val)方法,该方法又调用settx(self, val)。因此,我们有一个无限循环。

因此,设置属性值的正确方法是self._x = value

正确的代码:

class Property(object):
    def __init__(self):
        self._x = 'Raj'

    def gettx(self):
        print "getting x"
        return self._x

    def settx(self, val):
        print "Setting x"
        self._x = val #stores the value in _x. writing self.x = val would cause an infinite loop

    def dellx(self):
        print "deleting"
        del self._x    

    x = property(gettx, settx, dellx, "I'm object property")

p = Property()
print "p.x", p.x
p.x = "R"
print "p.x:", p.x

输出:

p.x getting x
Raj
Setting x
p.x: getting x
R