Problem Statement
Recently I came across this problem where I had to "swap" out a function in a Base class.
I had a base class Base
and a bunch of derived classes: Derived0..N
class Base:
def __init__(self, a, customs=None):
self.a = a
def base_func(self):
print(f'Printing from base: {self.a=}')
class Derived0(Base):
...
#
#
#
class DerivedN(Base):
...
I wanted some of the derived classes to use a custom function instead of the base_func
, i.e. override the functionality.
def custom_func(self):
print(f'Printing from fancy custom func: {self.a}')
Solution
Ideally, I should have simply overridden the Base class function, but I did not want to write the same implementation for each derived class.
Instead, I updated the base class to accept a way to override a member function, and let the derived classes pass along their implementation to swap out base functionality.
from functools import partial
class Base:
def __init__(self, a, customs=None):
self.a = a
self.customs = customs or {}
for func_name, func in self.customs.items():
current_func = getattr(self, func_name, None)
if callable(current_func):
setattr(self, func_name, partial(func, self))
def base_func(self):
print(f'Printing from base: {self.a=}')
Call changed to:
d = Derived0(5, {'base_func': custom_func})
d.base_func()
Prints:
Printing from fancy custom func: self.a=5
Use of partial
I used functools.partial to bind the function call with the object it will be called with, when called via derived class.
Use of self in custom function
self
will be required in the custom function to allow access to other attributes of that object.
Top comments (0)