I want to be able to create a concrete instance of a class that inherits from another concrete class, which in turn inherits from an abstract class.
The basic pattern is:
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()
When I try to create the instance of Baz
I get a RecursionError: maximum recursion depth exceeded
error. (As well as a pylint warning telling me that the signatures of the setter methods don't match the signatures of the base class)
However, if I remove the setters, I get an error self.x = x AttributeError: can't set attribute
What's the correct pattern to do this?
You need to change names for your x() / y() methods or for your x / y properties, for example rename
class Bar(Foo):
x = None
y = None
To:
class Bar(Foo):
x_val = None
y_val = None
And rename the references to x / y as well.
What you did is basically:
def x():
return x()
It happened because your def x
overridden the x = None
, so x is a function(property) that is calling itself. Avoid this by using another attribute(named differently) for storing the actual value of x.
Example from 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
Note: attribute names starting with underscore should be considered "private" and should not be directly accessed outside of the class. But it's only a convention for programmers, technically they are just normal attributes and you can do whatever you want, but it's nice to follow some convention, isn't it?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.