使用 @property 装饰器时在属性的 setter 方法中使用 super() 会引发 AttributeError [英] 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.
第一个示例设置了两个类,Parent
和 Child
.Parent
继承自 object
,而 Child
继承自 Parent
.属性 a
是使用属性装饰器定义的.当调用 child.a
的 setter 方法时,会引发 AttributeError
.
The first example sets up two classes, Parent
and Child
. Parent
inherits from object
, while Child
inherits from Parent
. The property a
is defined using the property decorator. When child.a
's setter method is called, an AttributeError
is raised.
在第二个示例中,通过使用 property()
函数而不是装饰器,一切都按预期进行.
In the second example, by using the property()
function rather than the decorator, everything works as would be expected.
谁能解释为什么行为不同?另外,是的,我知道 Child 中的 __init__
定义是不需要的.
Can anyone shed some light on why the behavior differs? Also, yes, I know that the __init__
definition in Child is not needed.
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
示例 1 返回 - 引发属性错误
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'
示例 2 - 使用 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
示例 2 返回 - 正常工作
a a
b bChild
推荐答案
super()
返回一个代理对象,不是超类,并且不支持函数 __set__()
.
super()
returns a proxy object, not a superclass, and it doesn't support the function __set__()
.
您可以在此处查看更多详细信息Python super 和设置父类属性 和这里 http://bugs.python.org/issue14965.
And you can see more details here Python super and setting parent class property and here http://bugs.python.org/issue14965.
这篇关于使用 @property 装饰器时在属性的 setter 方法中使用 super() 会引发 AttributeError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!