所以,我正在使用 Python 2.6 中的装饰器,但在让它们工作时遇到了一些麻烦。这是我的班级文件:

class testDec:

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

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

我认为这意味着治疗 x 就像属性一样,但是在 get 和 set 上调用这些函数。所以,我启动了 IDLE 并检查了它:

>>> from testDec import testDec
from testDec import testDec
>>> t = testDec()
t = testDec()
>>> t.x
t.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "testDec.py", line 18, in x
    return self._x
AttributeError: testDec instance has no attribute '_x'
>>> t.x = 5
t.x = 5
>>> t.x
t.x
5

显然,第一个调用按预期工作,因为我调用了 getter,并且没有默认值,并且它失败了。好的,好的,我明白了。但是,调用分配 t.x = 5 似乎创建了一个新属性 x, ,现在吸气剂不起作用了!

我缺少什么?

有帮助吗?

解决方案

你似乎正在使用 经典老派课程 在Python 2中。为了 特性 要正确工作,您需要使用 新式课堂 相反(在 python 2 中你必须 继承自 object)。只需将您的班级声明为 MyClass(object):

class testDec(object):

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

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

有用:

>>> k = testDec()
>>> k.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/devel/class_test.py", line 6, in x
    return self._x
AttributeError: 'testDec' object has no attribute '_x'
>>> k.x = 5
called setter
>>> k.x
called getter
5
>>> 

另一个可能导致问题的细节是,两种方法都需要相同的属性名称才能工作。 如果您使用这样的不同名称定义设置器,它将不起作用:

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

还有一件事一开始不太容易发现,那就是顺序:吸气剂 必须先定义. 。如果你先定义setter,你会得到 name 'x' is not defined 错误。

其他提示

对于谁绊倒在这里寻找这个异常等人刚一说明:这两种功能需要具有相同的名称。命名方法如下将导致异常:

@property
def x(self): pass

@x.setter
def x_setter(self, value): pass

相反给予这两种方法相同的名称

@property
def x(self): pass

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

同样重要的是要注意,声明事项的顺序。吸气必须在文件中的setter之前定义,否则你会得到一个NameError: name 'x' is not defined

您需要从对象派生类使用,你做新式的类:

class testDec(object):
   ....

然后,它应该工作。

在任何情况下,来这里从谷歌,除了上述的答案,我想补充一点,从基于的__init__方法调用设置时需要特别注意://计算器.COM / A /八十零万八千七百三十四分之三百九十四万二千一百十八“ >这个答案 具体做法是:

class testDec(object):                                                                                                                                            

    def __init__(self, value):
        print 'We are in __init__'
        self.x = value # Will call the setter. Note just x here
        #self._x = value # Will not call the setter

    @property
    def x(self):
        print 'called getter'
        return self._x # Note the _x here

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value # Note the _x here

t = testDec(17)
print t.x 

Output:
We are in __init__
called setter
called getter
17
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top