If I have this function, what should I do to replace the inner function with my own custom version?
def foo():
def bar():
# I want to change this
pass
# here starts a long list of functions I want to keep unchanged
def baz():
pass
Using classes this would be easily done overriding the method. Though, I can't figure out how to do that with nested functions. Changing foo
to be a class (or anything else) is not an option because it comes from a given imported module I can't modify.
Here's one way of doing it, creating a new foo that "does the right thing" by hacking the function internals. ( As mentioned by @DSM ). Unfortunately we cant just jump into the
foo
function and mess with its internals, as they're mostly marked read only, so what we have to do is modify a copy we construct by hand.I'm pretty sure its not going to catch all cases. But it works for the example (for me on an old python 2.5.1 )
Ugly bits that could do with some tidy up are:
co_consts
overriding only one member. All the info is in co_consts to determine which to replace - so a smarter function could do this. I dug into the internals by hand usingprint( foo.func_code.co_consts )
.You can find some information about the
CodeType
andFunctionType
by using the interpreter commandhelp( types.CodeType )
.UPDATE: I thought this was too ugly so I built a helper function to make it prettier. With the helper you can write:
Here's the implementation of
monkey_patch_fn
:You can pass it in as an optional parameter