在this question regarding reloading a module之后,如何从更改的模块中重新加载特定的函数?
伪代码:
from foo import bar
if foo.py has changed:
reload bar
发布于 2017-10-18 23:37:26
到目前为止,正确的方法是:
import sys, importlib
importlib.reload(sys.modules['foo'])
from foo import bar
在python 2.7,3.5,3.6上测试。
发布于 2011-09-01 21:43:46
热重载不是你可以在Python中可靠地完成的事情,而不会让你的头爆炸。如果不以特殊的方式编写代码,你就不能支持重载,而试图编写和维护支持重载的代码需要极端的纪律,而且太混乱了,不值得付出努力。测试这些代码也不是一件容易的事情。
解决方案是在代码发生更改时完全重新启动Python进程。可以无缝地做到这一点,但如何做取决于您的特定问题域。
发布于 2015-03-03 05:34:43
虽然重载函数不是reload
函数的一个功能,但它仍然是可能的。我不建议在生产环境中这样做,但它的工作原理是这样的:您要替换的函数是内存中某个地方的对象,并且您的代码可能包含许多对它的引用(而不是对函数名称的引用)。但该函数在被调用时实际执行的操作并不保存在该对象中,而是保存在另一个对象中,该对象反过来由function对象在其属性__code__
中引用。所以只要你有一个对函数的引用,你就可以更新它的代码:
模块mymod:
from __future__ import print_function
def foo():
print("foo")
其他模块/ python会话:
>>> import mymod
>>> mymod.foo()
foo
>>> old_foo_ref = mymod.foo
>>> # edit mymod.py to make function "foo" print "bar"
>>> reload(mymod)
<module 'mymod' from 'mymod.py'>
>>> old_foo_ref() # old reference is running old code
foo
>>> mymod.foo() # reloaded module has new code
bar
>>> old_foo_ref.__code__ = mymod.foo.__code__
>>> old_foo_ref() # now the old function object is also running the new code
bar
>>>
现在,如果您没有对旧函数的引用(即传递给另一个函数的lambda
),您可以通过搜索所有对象的列表,尝试使用gc
模块获取它:
>>> def _apply(f, x):
... return lambda: f(x)
...
>>> tmp = _apply(lambda x: x+1, 1) # now there is a lambda we don't have a reference to
>>> tmp()
2
>>> import gc
>>> lambdas = [obj for obj in gc.get_objects() if getattr(obj,'__name__','') == '<lambda>'] # get all lambdas
[<function <lambda> at 0x7f315bf02f50>, <function <lambda> at 0x7f315bf12050>]
# i guess the first one is the one i passed in, and the second one is the one returned by _apply
# lets make sure:
>>> lambdas[0].__code__.co_argcount
1 # so this is the "lambda x: ..."
>>> lambdas[1].__code__.co_argcount
0 # and this is the "lambda: ..."
>>> lambdas[0].__code__ = (lambda x: x+2).__code__ # change lambda to return arg + 2
>>> tmp()
3 #
>>>
https://stackoverflow.com/questions/7271082
复制相似问题