为什么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