0

Is there a standard way for creating class level variables in an abstract base class (ABC) that we want derived classes to define?

I could implement this with properties as follows:

from abc import ABC
from abc import abstractmethod

class Parent(ABC):
    @property
    @abstractmethod
    def provider(self) -> str:
        """The provider that the payload generator is applicable for"""
        raise NotImplementedError()

class Child(Parent):
    @property
    def provider(self) -> str:
        return 'some provider'

But properties are linked to instances and not classes. Is there a way I can implement similar functionality for a class variable in Python 3.6+?

Gaurav Keswani
  • 431
  • 4
  • 14

1 Answers1

0

Use a custom metaclass:

class RequireProperty(type):

    _required = ['define_me']

    def __new__(cls, name, bases, attributes):

        new_class = super().__new__(cls, name, bases, attributes)
        if not all(required_attribute in attributes for required_attribute in cls._required):
            raise TypeError

        else:
            return new_class

If you don't define the attribute:

class DidntDefine(metaclass=RequireProperty):
    pass

DidntDefine()

Output:

TypeError: You must define all of ['define_me'].

If you do:

class DidDefine(metaclass=RequireProperty):

    define_me = None

DidDefine()

Output:

<__main__.DidDefine at 0x2bcec632198>
gmds
  • 19,325
  • 4
  • 32
  • 58