I want to define an abstract class in python 3.6 that enforces the presence of certain properties. From the docs it appears that you have to define abstract properties as getter/setter functions, even if you don't intend to use getter/setter functions with the properties.
Following the recipe in the docs I created an abstract class with two properties : name
and description
. One read/write the other read only.
import abc
class AbstractTestClass(abc.ABC):
def __init__(self):
""" Constructor
"""
pass
def __repr__(self):
return 'AbstractTestClass'
@property
@abc.abstractmethod
def name(self):
return 'Not defined'
@name.setter
@abc.abstractmethod
def name(self):
pass
@property
@abc.abstractmethod
def description(self):
return 'Not defined'
What I wanted was to be able to create a class based on the abstract class in a simple manner like this:
class ConcreteClass1(AbstractTestClass):
"""
Simple class definition
"""
def __init__(self):
# Set values to properties using simple assignment
self.name = 'Concrete class 1'
self.description = 'Concrete class 1 description'
I just want to make sure that the name and description properties have always been defined. However if I create an instance of this class then it throws the error
class1 = ConcreteClass1()
TypeError: Can't instantiate abstract class ConcreteClass1 with abstract methods description, name
As an exercise I created another class from the abstract one:
class ConcreteClass2(AbstractTestClass):
"""
This class works but it's not what I want
"""
def __init__(self):
# define private variable for name
self._name = 'Concrete class 2'
@property
def name(self):
return self._name
@name.setter
def name(self,value):
self._name = value
@property
def description(self):
return 'Concrete class 2 description'
This works, it instantiates, but it's ugly and verbose, and it feels like the abstract class is not helping me.
Is there a way to implement something more like ConcreteClass1
that's concise and streamlined? Or do I just put the properties into the abstract class __init__()
function and require that sub classes must call the super().__init__()
?