一只猴子如何在python中修补一个函数? [英] How does one monkey patch a function in python?
问题描述
我无法用另一个函数替换来自不同模块的函数,这让我发疯.
I'm having trouble replacing a function from a different module with another function and it's driving me crazy.
假设我有一个看起来像这样的模块 bar.py:
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()
我希望得到结果:
Something expensive!
Something really cheap.
Something really cheap.
但我得到了这个:
Something expensive!
Something expensive!
Something expensive!
我做错了什么?
推荐答案
思考 Python 命名空间的工作原理可能会有所帮助:它们本质上是字典.所以当你这样做时:
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.'
这样想:
do_something_expensive = a_package.baz['do_something_expensive']
do_something_expensive = lambda: 'Something really cheap.'
希望你能意识到为什么这不起作用 :-) 一旦你将一个名字导入到命名空间中,你导入的命名空间中的名字的值 from 是无关紧要的.您只是在上面的本地模块的命名空间或 a_package.baz 的命名空间中修改 do_something_expensive 的值.但是因为 bar 直接导入 do_something_expensive ,而不是从模块命名空间引用它,你需要写入它的命名空间:
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.'
这篇关于一只猴子如何在python中修补一个函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!