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 this:
from a_package.baz import do_something_expensive
def a_function():
print do_something_expensive()
And I have another module that looks like this:
from bar import a_function
a_function()
from a_package.baz import do_something_expensive
do_something_expensive = lambda: 'Something really cheap.'
a_function()
import a_package.baz
a_package.baz.do_something_expensive = lambda: 'Something really cheap.'
a_function()
I would expect to get the results:
Something expensive!
Something really cheap.
Something really cheap.
But instead I get this:
Something expensive!
Something expensive!
Something expensive!
What am I doing wrong?
It may help to think of how Python namespaces work: they're essentially dictionaries. So when you do this:
from a_package.baz import do_something_expensive
do_something_expensive = lambda: 'Something really cheap.'
think of it like this:
do_something_expensive = a_package.baz['do_something_expensive']
do_something_expensive = lambda: 'Something really cheap.'
Hopefully you can realize why this doesn't work then :-) Once you import a name into a namespace, the value of the name in the namespace you imported from is irrelevant. You're only modifying the value of do_something_expensive in the local module's namespace, or in a_package.baz's namespace, above. But because bar imports do_something_expensive directly, rather than referencing it from the module namespace, you need to write to its namespace:
import bar
bar.do_something_expensive = lambda: 'Something really cheap.'