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:
class SomeClass(object): def __init__(self): self.a = 42 def show(self): print self.a
import thirdpartymodule_a def dosomething(): sc = thirdpartymodule_a.SomeClass() sc.show()
import thirdpartymodule_b thirdpartymodule.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.
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_b.SomeClass.__init__ = new_init.
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