[英]Using super() in a property's setter method when using the @property decorator raises an AttributeError
I am a little confused by the behavior when attempting to overwrite a property in a subclass. 尝试覆盖子类中的属性时,我对行为有些困惑。
The first example sets up two classes, Parent
and Child
. 第一个示例设置两个类
Parent
和Child
。 Parent
inherits from object
, while Child
inherits from Parent
. Parent
从object
继承,而Child
从Parent
继承。 The property a
is defined using the property decorator. 使用属性装饰器定义属性
a
。 When child.a
's setter method is called, an AttributeError
is raised. child.a
的setter方法时,将引发AttributeError
。
In the second example, by using the property()
function rather than the decorator, everything works as would be expected. 在第二个示例中,通过使用
property()
函数而不是装饰器,一切都会按预期进行。
Can anyone shed some light on why the behavior differs? 谁能阐明为什么行为不同? Also, yes, I know that the
__init__
definition in Child is not needed. 另外,是的,我知道不需要Child中的
__init__
定义。
@property
@property
class Parent(object):
def __init__(self):
self._a = 'a'
@property
def a(self):
return self._a
@a.setter
def a(self, val):
self._a = val
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
@property
def a(self):
return super(Child, self).a
@a.setter
def a(self, val):
val += 'Child'
super(Child, self).a = val
p = Parent()
c = Child()
print p.a, c.a
p.a = 'b'
c.a = 'b'
print p.a, c.a
a a
Traceback (most recent call last):
File "testsuper.py", line 26, in <module>
c.a = 'b'
File "testsuper.py", line 20, in a
super(Child, self).a = val
AttributeError: 'super' object has no attribute 'a'
Using property()
Using property()
class Parent(object):
def __init__(self):
self._a = 'a'
def _get_a(self):
return self._a
def _set_a(self, val):
self._a = val
a = property(_get_a, _set_a)
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
def _get_a(self):
return super(Child, self)._get_a()
def _set_a(self, val):
val = val+'Child'
super(Child, self)._set_a(val)
a = property(_get_a, _set_a)
p = Parent()
c = Child()
print p.a, c.a
p.a = 'b'
c.a = 'b'
print p.a, c.a
a a
b bChild
super()
returns a proxy object, not a superclass, and it doesn't support the function __set__()
. super()
返回一个代理对象,而不是超类,并且不支持__set__()
函数。
And you can see more details here Python super and setting parent class property and here http://bugs.python.org/issue14965 . 并且您可以在此处的Python super和设置父类属性以及此处的http://bugs.python.org/issue14965中看到更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.