设置继承属性的值

时间:2016-02-16 22:26:23

标签: python oop python-3.x inheritance

我希望能够创建一个继承自另一个具体类的类的具体实例,该类继承自抽象类。

基本模式是:

from abc import ABCMeta, abstractproperty

class Foo(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def x(self):
        pass

    @abstractproperty
    def y(self):
        pass

class Bar(Foo):
    x = None
    y = None

    def __init__(self, x, y):
        self.x = x
        self.y = y

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

    @x.setter
    def x(self, value):
        self.x = value

    @property
    def y(self):
        return self.y

    @y.setter
    def y(self, value):
        self.y = value

class Baz(Bar):

    def __init__(self):
        super().__init__(x=2, y=6)


a = Baz()

当我尝试创建Baz的实例时,出现RecursionError: maximum recursion depth exceeded错误。 (以及一个pylint警告告诉我,setter方法的签名不符合基类的签名)

但是,如果删除setter,我会收到错误self.x = x AttributeError: can't set attribute

这样做的正确模式是什么?

2 个答案:

答案 0 :(得分:1)

您需要更改x()/ y()方法或x / y属性的名称,例如重命名

class Bar(Foo):
    x = None
    y = None

要:

class Bar(Foo):
    x_val = None
    y_val = None

并重命名对x / y的引用。

答案 1 :(得分:1)

你所做的基本上是:

def x():
    return x()

之所以发生这种情况是因为def x覆盖了x = None,因此x是一个调用自身的函数(属性)。通过使用另一个属性(命名方式不同)来存储x的实际值来避免这种情况。

python docs(https://docs.python.org/3.5/library/functions.html#property)的示例:

class C:
    def __init__(self):
        self._x = None

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

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

注意:以下划线开头的属性名称应视为“私有”,不应在类外部直接访问。但它只是程序员的惯例,从技术上讲它们只是普通属性,你可以做任何你想做的事情,但遵循一些约定很好,不是吗?