1

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__()?

glibdud
  • 7,550
  • 4
  • 27
  • 37
Redlegjed
  • 187
  • 2
  • 11
  • The short answer is that python can't define abstract properties for instance properties. See [this answer](https://stackoverflow.com/questions/51055750/python-abstract-instance-variable) for details. – Redlegjed Jan 29 '22 at 13:55

0 Answers0