I try to achieve the following:
class_variable
to be "implemented" in ConcreteSubClass
of AbstractSuperClass
, i.e. make AbstractSuperClass.class_variable
abstractmethod
in AbstractSuperClass
which accesses the "implemented" value of ConcreteSubClass.class_variable
I would like to do this so that I won't have to implement method
within all ConcreteSubClass
es of AbstractSuperClass
.
If I run the below code:
from abc import ABC
class AbstractSuperClass(ABC):
class_variable: int
def method(self):
return self.instance_variable * AbstractSuperClass.class_variable
class ConcreteSubClass(AbstractSuperClass):
class_variable: int = 2
def __init__(self, instance_variable):
self.instance_variable = instance_variable
concrete_subclass = ConcreteSubClass(instance_variable=2)
print(concrete_subclass.method())
The code fails with:
Traceback (most recent call last):
File "<input>", line 19, in <module>
File "<input>", line 8, in function
AttributeError: type object 'AbstractSuperClass' has no attribute 'class_variable'
Which is reasonable, because the value of class_variable
is not assigned in AbstractSuperClass
, but suspicious because AbstractSuperClass
has attribute class_variable
.
I would like to achieve the below:
def method(self):
return self.instance_variable * <refer to cls of the concrete subclass this method will be called>.class_variable
How can I do this?
Based on @a_r's code, I came up with the solution where most of the code is in AbstractSuperClass
and ConcreteSubClass
es only need to define and implement minimal stuff:
from abc import ABC
class AbstractSuperClass(ABC):
_class_variable: int
@classmethod
def class_variable(cls) -> int:
return cls._class_variable
def method(self):
return self.instance_variable * self.class_variable()
class ConcreteSubClass(AbstractSuperClass):
_class_variable: int = 2
def __init__(self, instance_variable):
self.instance_variable = instance_variable
concrete_subclass = ConcreteSubClass(instance_variable=2)
print(concrete_subclass.method())