Reputation: 26983
Python does not provide some built-in inheritance mechanism to call implementations of base virtual or abstract methods in the derived class from the base methods
I am wondering what is the closest thing in python that would provide the following structure:
class Base(?):
def some_abstract_interface(self, **params):
raise Unimplemented()
def some_base_impl(self):
self.some_abstract_interface(self, a=4, b=3, c=2)
class Derived(Base):
@neat_override_decorator_here?
def some_abstract_interface(self, **params):
print("actual logic here {0}".format(params))
d = Derived()
d.some_base_impl()
>>>output: actual logic here a=4, b=3, c=2
Upvotes: 1
Views: 77
Reputation: 107005
You can already do that without any neat decorator:
class Base:
def some_abstract_interface(self):
raise NotImplemented
def some_base_impl(self):
self.some_abstract_interface()
class Derived(Base):
def some_abstract_interface(self):
print('actual logic here')
Derived().some_base_impl()
This outputs:
actual logic here
If you want to enforce that Base
is an abstract class and cannot be used to instantiate an object directly, and that some_abstract_interface
is meant to be an abstract method and always has to be overridden by an implementation of the method from a child class, you can make the base class inherit from the ABC
class of the abc
module and decorate abstract methods with abc.abstractmethod
like this:
import abc
class Base(abc.ABC):
@abc.abstractmethod
def some_abstract_interface(self):
raise NotImplemented
def some_base_impl(self):
self.some_abstract_interface()
class Derived(Base):
def some_abstract_interface(self):
print('actual logic here')
Derived().some_base_impl()
Upvotes: 6
Reputation: 532053
You simply make the call yourself. That's not going to be any heavier, syntactically, then the decorator you posit.
class Derived(Base):
def some_abstract_interface(self, **params):
self.some_base_impl()
print('actual logic her {0}.format(params))
In fact, you don't even need to separate some_base_impl
and some_abstract_interace
; an abstract method can have an implementation but still require overriding.
from abc import ABC, abstractmethod
class Base(ABC):
@abstractmethod
def some_abstract_interface(self, **params):
pass # Put base implementation here
class Derived(Base):
def some_abstract_interface(self, **params):
super().some_abstract_interface(**params)
print("actual logic here {0}".format(params))
Upvotes: 4