TR.*_*TR. 153 python decorator new-style-class
所以,我正在使用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
Run Code Online (Sandbox Code Playgroud)
我认为这意味着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
Run Code Online (Sandbox Code Playgroud)
很明显,第一个调用按预期工作,因为我调用了getter,并且没有默认值,并且它失败了.好的,好的,我理解.然而,对assign的调用t.x = 5似乎创建了一个新属性x,现在getter不起作用!
我错过了什么?
nos*_*klo 301
您似乎在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
Run Code Online (Sandbox Code Playgroud)
有用:
>>> 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
>>>
Run Code Online (Sandbox Code Playgroud)
可能导致问题的另一个细节是两个方法都需要相同的名称才能使属性起作用.如果您使用不同的名称定义setter,它将无法工作:
@x.setter
def x_setter(self, value):
...
Run Code Online (Sandbox Code Playgroud)
还有一件事情,一开始并不容易发现,是顺序:必须首先定义吸气剂.如果先定义setter,则会 name 'x' is not defined出现错误.
And*_*ows 77
对于在这里偶然发现寻找此异常的其他人的注意事项:两个函数都需要具有相同的名称.如下命名方法将导致异常:
@property
def x(self): pass
@x.setter
def x_setter(self, value): pass
Run Code Online (Sandbox Code Playgroud)
而是给两个方法命名相同
@property
def x(self): pass
@x.setter
def x(self, value): pass
Run Code Online (Sandbox Code Playgroud)
同样重要的是要注意声明的顺序很重要.必须在文件中的setter之前定义getter,否则你将得到一个NameError: name 'x' is not defined
MrT*_*opf 22
您需要使用通过从对象派生类来执行的新式类:
class testDec(object):
....
Run Code Online (Sandbox Code Playgroud)
然后它应该工作.
ako*_*ian 10
如果有人从谷歌来到这里,除了上面的答案,我想补充一点,__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 t.x
Output:
We are in __init__
called setter
called getter
17
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
68411 次 |
| 最近记录: |