DEV Community

chaitdwivedi
chaitdwivedi

Posted on

Swap Base class methods in Python

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): 
  ...

Enter fullscreen mode Exit fullscreen mode

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}')
Enter fullscreen mode Exit fullscreen mode

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=}')

Enter fullscreen mode Exit fullscreen mode

Call changed to:

d = Derived0(5, {'base_func': custom_func})
d.base_func()
Enter fullscreen mode Exit fullscreen mode

Prints:

Printing from fancy custom func: self.a=5
Enter fullscreen mode Exit fullscreen mode

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)