Search code examples
pythonmonkeypatching

How to extend Class instance


MyClass is defined in module.py. There is no way we can modify it. But we do know the Class definition looks like this:

class MyClass:
    def method(self, msg):
        print 'from method:', msg

I start my script with importing the module and then declaring an object's instance:

import module    
foo = module.MyClass()

Then I write my own function:

def function(msg):
    print 'from function:', msg

Now, every time foo.method('') is used I want to call function() so it prints the same message too.

Would this situation be referred as the monkey patching? How to achieve what is needed?


Solution

  • Yes, it's called monkey-patching.

    This is basically decoration, but done manually after the class is already defined.

    from functools import wraps
    
    def wrapper(f):
        @wraps(f)
        def wrapped(*args, **kwargs):
            myFunction()
            return f(*args, **kwargs)
        return wrapped
    
    MyClass.printThis = wrapper(MyClass.printThis)
    

    It will affect all instances of MyClass, even those that were created before the patch was applied.

    If you don't need to dynamically modify runtime behaviour, avoid monkey-patching and prefer to use inheritance to customise behaviour, as suggested in the comments. It's less hacky.