【发布时间】:2012-11-28 00:14:38
【问题描述】:
我对尝试覆盖子类中的属性时的行为感到有些困惑。
第一个示例设置了两个类,Parent 和 Child。 Parent 继承自 object,而 Child 继承自 Parent。属性a 是使用属性装饰器定义的。当child.a 的setter 方法被调用时,会引发AttributeError。
在第二个示例中,通过使用 property() 函数而不是装饰器,一切都按预期工作。
谁能解释为什么行为不同?另外,是的,我知道 Child 中的 __init__ 定义是不需要的。
示例 1 - 使用 @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
示例 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 - 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
示例 2 返回 - 正常工作
a a
b bChild
【问题讨论】:
-
我的第一个建议是在这种情况下不要使用装饰器形式。 (我发现它实际上很烦人,但对于只读属性)
-
即便如此,还是有点奇怪。
-
我在第 12 行
super(Child, self).a = val--TypeError: super(type, obj): obj must be an instance or subtype of type上收到示例 1 的不同错误。 -
谢谢。当我复制和粘贴时,我以某种方式使用来自
Child的设置器作为Parent中的设置器。现在应该修好了。 -
即使您进行了更改,我也会遇到不同的错误。现在在第 20 行
super(Child, self).a = val--AttributeError: 'super' object has no attribute 'a'。
标签: python python-2.7