'无法在Python中使用新样式属性设置属性'

Max*_*vko 67 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
Run Code Online (Sandbox Code Playgroud)

并在控制台中查看以下内容:

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

我究竟做错了什么?PS:旧式宣言工作正常.

Dav*_*ebb 97

文档说明以下关于使用装饰器形式property:

请务必为其他函数指定与原始属性相同的名称(在本例中为x).

我不知道为什么会这样,因为如果你使用property函数来返回属性,可以随意调用方法.

因此,您需要将代码更改为以下内容:

@x.setter
def x(self, value):
    'setting'
    self._x = value
Run Code Online (Sandbox Code Playgroud)

  • 什么是“设置”字符串? (2认同)
  • @yourfriendzak - 这是一个文档字符串http://www.python.org/dev/peps/pep-0257/ (2认同)
  • @flonk:这是相当技术性的,但是 Python 使用方法名称(在 `def` 行)作为属性名称做了一些魔术。因此,在 OP 的情况下,他定义了一个名为 `set_x` 的方法并将其装饰为 setter,他实际上创建了一个名为 `set_x` 的可设置属性!因此,他可以做的不是`cx = 10`,而是`c.set_x = 10`。请注意,装饰器中的名称无关紧要。如果他有两个属性,`x` 和 `y`,他可以很容易地使用 `@x.setter` 或 `@y.setter` 将 `set_x` 转换为一个 setter 属性(为 `self ._x`)。 (2认同)

Ign*_*ams 14

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

@x.setter
def x(self, value):
 ...
Run Code Online (Sandbox Code Playgroud)


Kyl*_*yle 6

当你调用@ x.setter,@ x.getter或@ x.deleter时,你正在创建一个新的属性对象,并为它提供你正在装饰的函数的名称.所以真的,最重要的是上次在类定义中使用@ x.*er装饰器时,它具有您实际想要使用的名称.但是,由于这会使您的类命名空间被您希望使用的属性的不完整版本污染,因此最好使用相同的名称来清理它们.