Search code examples
pythonclasscode-injection

How to change one class in an external package for my use?


I use an external pacakge which I bring in via pip.

This package has a structure as follows:

class OuterThing:
  field: Innerthing
  def outer_method1(self...

class InnerThing():
   def inner_method1(self,...
   def inner_method2(self,...
   def inner_method3(self,...

I instantiate only OuterThing objects (which then internally instantiate InnerThing objects).

I want the inner thing objects to have all the normal fields and methods, just inner_method1 I need to customise a bit for my use.

What is the shortest way (i.e. the way with the least code) to do this?

I do not want to copy the whole package into my source tree if possible, just "inject" the changes at runtime (but possibly before all instantiations) to the specified method in InnerThing.


Solution

  • In Python, a method is just an attribute of the class object that happens to be a function having self as its first parameter. That means that you can easily replace it by your own function, provided you keep the same signature. You can even call the original method from your own one:

    # after having imported InnerThing
    _orig_inner_method1 = InnerThing.inner_method1
    
    def _patched_inner_method1(self, ...):
        # your own code
        ...
        _orig_inner_method1(self, ...)   # eventually call the original method
        ...
    
    InnerThing.inner_method1 = _patched_inner_method1
    

    From that point, any InnerThing object created will use your patched method.