属性是否支持继承?

时间:2016-07-11 07:34:22

标签: python inheritance properties

在我的代码类A中有一个属性,但类B不会继承它。 @property是否支持继承?还是我的错?

class A(object):

    def __init__(self):
        self._x = 100

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, v):
        self._x = v


class B(A):

    @x.setter
    def x(self, v):
        self._x = v

错误信息如下:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    class B(A):
  File "test.py", line 10, in B
    @x.setter
NameError: name 'x' is not defined

2 个答案:

答案 0 :(得分:4)

NameError是因为x不在全球范围内;它是在A的类名称空间中定义的,因此您需要使用A.x显式访问它。这是一个非常常见的错误,例如, python subclass access to class variable of parent

但是,对于属性,它可能会稍微复杂一些。如果您在B添加新的setter ,那么A.x.setter中使用A就没有问题。但是,如果覆盖现有的setter ,则还会改变A的行为。我怀疑这是你想要的行为。

相反,在这种情况下,您需要在子类中使用class B(A): x = property(A.x.__get__) # new property with same getter @x.setter # new setter on new property def x(self, v): ... 的getter和新的setter创建一个新属性。我认为这是实现这一目标的最简单方法,重复次数最少:

property

请注意@没有A句法糖的用法,因为我没有使用它来装饰新方法。如果您想从B的setter访问super().x.__set__(whatever)的setter,可以使用__m256进行设置。

答案 1 :(得分:2)

它只是不知道从哪里获取x。你可以这样做:

class A(object):
    def __init__(self):
        self._x = 100

    @property
    def x(self):
        return self._x

class B(A):
    @A.x.setter
    def x(self, v):
        self._x = v