Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monkey patching a class in another module in Python

I'm working with a module written by someone else. I'd like to monkey patch the __init__ method of a class defined in the module. The examples I have found showing how to do this have all assumed I'd be calling the class myself (e.g. Monkey-patch Python class). However, this is not the case. In my case the class is initalised within a function in another module. See the (greatly simplified) example below:

thirdpartymodule_a.py

class SomeClass(object):     def __init__(self):         self.a = 42     def show(self):         print self.a 

thirdpartymodule_b.py

import thirdpartymodule_a def dosomething():     sc = thirdpartymodule_a.SomeClass()     sc.show() 

mymodule.py

import thirdpartymodule_b thirdpartymodule_b.dosomething() 

Is there any way to modify the __init__ method of SomeClass so that when dosomething is called from mymodule.py it, for example, prints 43 instead of 42? Ideally I'd be able to wrap the existing method.

I can't change the thirdpartymodule*.py files, as other scripts depend on the existing functionality. I'd rather not have to create my own copy of the module, as the change I need to make is very simple.

Edit 2013-10-24

I overlooked a small but important detail in the example above. SomeClass is imported by thirdpartymodule_b like this: from thirdpartymodule_a import SomeClass.

To do the patch suggested by F.J I need to replace the copy in thirdpartymodule_b, rather than thirdpartymodule_a. e.g. thirdpartymodule_b.SomeClass.__init__ = new_init.

like image 914
Snorfalorpagus Avatar asked Oct 23 '13 15:10

Snorfalorpagus


People also ask

How do you use monkey patch in Python?

In Python, the term monkey patch refers to dynamic (or run-time) modifications of a class or module. In Python, we can actually change the behavior of code at run-time. We use above module (monk) in below code and change behavior of func() at run-time by assigning different value.

What is monkey patching and is it ever a good idea?

Monkey patching is good for testing or mocking out behavior. They can be localized in factory/class decorators/metaclasses where they create a patched new class/object from another object to help with "cross-cutting concerns" in between ALL methods like logging/memoization/caching/database/persistance/unit conversion.

What is monkey patching and is it ever a good idea Python?

Monkey patching is reopening the existing classes or methods in class at runtime and changing the behavior, which should be used cautiously, or you should use it only when you really need to. As Python is a dynamic programming language, Classes are mutable so you can reopen them and modify or even replace them.

What is multi patching in Python?

Monkey Patching is an exciting topic of Python. Monkey-patching is a term that refers to modifying a class or module at a run time. In simple words, a class or module's work can be changed at the runtime. Let's understand this concept by real-life example.


Video Answer


1 Answers

The following should work:

import thirdpartymodule_a import thirdpartymodule_b  def new_init(self):     self.a = 43  thirdpartymodule_a.SomeClass.__init__ = new_init  thirdpartymodule_b.dosomething() 

If you want the new init to call the old init replace the new_init() definition with the following:

old_init = thirdpartymodule_a.SomeClass.__init__ def new_init(self, *k, **kw):     old_init(self, *k, **kw)     self.a = 43 
like image 124
Andrew Clark Avatar answered Oct 07 '22 19:10

Andrew Clark