Skip to content Skip to sidebar Skip to footer

Python: Hierarchy Of Abstract Classes Without Abstract Methods

So, here is a problem: I want to define an abstract class, let's say AbstractA, which does not require subclasses to implement any of its methods, but rather to extend its functio

Solution 1:

Here's possible solution:

classAbstractA:
    _is_abstract = Truedef__init__(self):
        if self._is_abstract:
            raise RuntimeError("Abstract class instantiation.")
        # do initialization stuffdef__init_subclass__(self):   # is called every time class is subclassed
        self._is_abstract = False# thus makes sure abstract check fails on a subclassclassAbstractMixin:
    def__init_subclass__(self):
        self._is_abstract = TrueclassAbstractB(AbstractMixin, AbstractA):  # AbstractMixin takes precendence on MRO,# inherit __init__                      # so the class abstract check returns True.def__init_subclass__(self):
        self._is_abstract = FalseclassA(AbstractA):
    passclassB(AbstractB):
    pass

AbstractA()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __init__
RuntimeError: Abstract classinstantiation.

AbstractB()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __init__
RuntimeError: Abstract classinstantiation.

A()
<__main__.A object at 0x7f0bba5112e8>

B()
<__main__.B object at 0x7f0bba511438>

Solution 2:

classA(object):

    def__init__(self):
        if self.__class__ == A:
            raise RuntimeError("Abstract class instantiation.")
        print(self.__class__.__name__)


classB(A):
    pass
>>> A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __init__
RuntimeError: Abstract class instantiation.
>>>B()
B
<__main__.B object at 0x7f8c816a58d0>
>>>

Solution 3:

In Python, you would probably implement the "abstract" base classes as mix-ins. There's nothing special you need to do; by convention, you would add Mixin to the name to indicate that it isn't meant to be instantiated directly, but simply used as a base class for other classes.

classAMixin:def__init__(self):
        # do initialization stuffdefvery_common_method(self, ...):
        # do very common stuffclassBMixin(AMixin):# do not duplicate initialization stuff here, inherit insteaddefless_common_method(self, ...):
        # do less common stuffclassAX(AMixin):defspecific_method_1(self, ...):

classBX(BMixin):defspecific_method_2(self, ...):

classFoo:
    ...

classBar(Foo, BMixin):
    ...

Post a Comment for "Python: Hierarchy Of Abstract Classes Without Abstract Methods"