2010-11-15 96 views
52

我试图用新的样式属性声明:“无法设置属性”与新样式属性在Python

class C(object): 
    def __init__(self): 
     self._x = 0 

    @property 
    def x(self): 
     print 'getting' 
     return self._x 

    @x.setter 
    def set_x(self, value): 
     print 'setting' 
     self._x = value 

if __name__ == '__main__': 
    c = C() 
    print c.x 
    c.x = 10 
    print c.x 

并查看控制台以下:

pydev debugger: starting 
getting 
0 
File "\test.py", line 55, in <module> 
c.x = 10 
AttributeError: can't set attribute 

我究竟做错了什么? P.S .:旧式宣言正常。

+0

我已经回滚了将'setting'(一个文档字符串)变成'print'setting'(一个简单的调试语句)的编辑。虽然打印语句的意图确实是合理的,但文档字符串中没有任何伤害或错误,它根本不会影响问题。 – 2016-01-18 22:10:40

回答

76

The documentation says the following有关使用的property装饰形式:(X在这种情况下)

一定要给予额外的功能相同的名称与原始属性

我有不知道为什么这是因为如果你使用property作为函数返回一个属性的方法可以调用任何你喜欢的。

所以,你需要更改您的代码如下:

@x.setter 
def x(self, value): 
    'setting' 
    self._x = value 
+0

啊,太棒了,我在另一个地方看到了这个,但是认为他们可能对python缺乏方法重载不知道。这实际上看起来比'set_x'的名称更清洁! :) – Darthfett 2012-02-23 16:22:50

+0

什么是“设置”字符串? – zakdances 2013-03-04 22:47:03

+1

@yourfriendzak - 这是一个文档字符串http://www.python.org/dev/peps/pep-0257/ – 2013-03-12 10:45:10

13

setter方法必须与getter具有相同的名称。别担心,装饰者知道如何区分他们。

@x.setter 
def x(self, value): 
... 
6

当你调用@ x.setter,@ x.getter,或@ x.deleter,你要创建一个新的属性和对象给它你正在装饰的功能的名称。所以,真正重要的是,你最后一次在类定义中使用@ x。* er装饰器,它有你实际想要使用的名称。但是,由于这会让您的类名称空间受到您希望使用的属性的不完整版本的污染,所以最好使用相同的名称进行清理。