繁体   English   中英

使用@property装饰器时在属性的setter方法中使用super()会引发AttributeError

[英]Using super() in a property's setter method when using the @property decorator raises an AttributeError

尝试覆盖子类中的属性时,我对行为有些困惑。

第一个示例设置两个类ParentChild Parentobject继承,而ChildParent继承。 使用属性装饰器定义属性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 return-引发属性错误

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

super()返回一个代理对象,而不是超类,并且不支持__set__()函数。

并且您可以在此处的Python super和设置父类属性以及此处的http://bugs.python.org/issue14965中看到更多详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM