我希望能够创建一个继承自另一个具体类的类的具体实例,该类继承自抽象类。
基本模式是:
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
这样做的正确模式是什么?
答案 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
注意:以下划线开头的属性名称应视为“私有”,不应在类外部直接访问。但它只是程序员的惯例,从技术上讲它们只是普通属性,你可以做任何你想做的事情,但遵循一些约定很好,不是吗?