为什么Python中的@ foo.setter不适合我?

所以,我正在使用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() >>> tx tx 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' >>> tx = 5 tx = 5 >>> tx tx 5 

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

我错过了什么?

你似乎在使用经典的旧式课程 。 为了使属性正常工作,您需要使用新样式类 ( inheritance自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() >>> kx 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' >>> kx = 5 called setter >>> kx called getter 5 >>> 

只是为了寻找这个exception而绊倒在这里的其他人注意到:两个函数都需要具有相同的名称。 如下命名方法将导致一个例外:

 @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 

您需要使用从对象中派生类的新类风格:

 class testDec(object): .... 

那么它应该工作。

如果有人从谷歌来到这里,除了上面的答案,我想补充一点,当从基于这个答案的类的__init__方法中调用setter时,需要特别注意。具体来说:

 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 tx Output: We are in __init__ called setter called getter 17 
Interesting Posts