使用 @property 装饰器时在属性的 setter 方法中使用 super() 会引发 AttributeError [英] Using super() in a property's setter method when using the @property decorator raises an AttributeError

查看:39
本文介绍了使用 @property 装饰器时在属性的 setter 方法中使用 super() 会引发 AttributeError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对尝试覆盖子类中的属性时的行为感到有些困惑.

I am a little confused by the behavior when attempting to overwrite a property in a subclass.

第一个示例设置了两个类,ParentChild.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆