I\'m having trouble replacing a function from a different module with another function and it\'s driving me crazy.
Let\'s say I have a module bar.py that looks like
In the first snippet, you make bar.do_something_expensive
refer to the function object that a_package.baz.do_something_expensive
refers to at that moment. To really "monkeypatch" that you would need to change the function itself (you are only changing what names refer to); this is possible, but you do not actually want to do that.
In your attempts to change the behavior of a_function
, you have done two things:
In the first attempt, you make do_something_expensive a global name in your module. However, you are calling a_function
, which does not look in your module to resolve names, so it still refers to the same function.
In the second example you change what a_package.baz.do_something_expensive
refers to, but bar.do_something_expensive
is not magically tied to it. That name still refers to the function object it looked up when it was initilized.
The simplest but far-from-ideal approach would be to change bar.py
to say
import a_package.baz
def a_function():
print a_package.baz.do_something_expensive()
The right solution is probably one of two things:
a_function
to take a function as an argument and call that, rather than trying to sneak in and change what function it is hard coded to refer to, orUsing globals (this is what changing module-level stuff from other modules is) is a bad thing that leads to unmaintainable, confusing, untestestable, unscalable code the flow of which is difficult to track.