我有一个长期运行的Python服务器,希望能够在不重新启动服务器的情况下升级服务。最好的方法是什么?
if foo.py has changed:
unimport foo <-- How do I do this?
import foo
myfoo = foo.Foo()
我有一个长期运行的Python服务器,希望能够在不重新启动服务器的情况下升级服务。最好的方法是什么?
if foo.py has changed:
unimport foo <-- How do I do this?
import foo
myfoo = foo.Foo()
当前回答
对于Python 2,使用内置函数reload:
reload(module)
对于Python 2和Python 3.2-3.3,使用reload from module imp:
import imp
imp.reload(module)
对于Python≥3.4,imp已弃用,改用importlib,因此使用以下命令:
import importlib
importlib.reload(module)
or:
from importlib import reload
reload(module)
TL; diana:
Python≥3.4:importlib.reload(module) Python 3.2 - 3.3: imp.reload(module) Python 2: reload(module)
其他回答
我遇到了很多麻烦,试图在Sublime Text中重新加载一些东西,但最后我可以编写这个实用程序来基于sublime_plugin.py用于重新加载模块的代码在Sublime Text上重新加载模块。
下面的代码允许您从名称上带有空格的路径重新加载模块,然后在重新加载后,您可以像往常一样导入。
def reload_module(full_module_name):
"""
Assuming the folder `full_module_name` is a folder inside some
folder on the python sys.path, for example, sys.path as `C:/`, and
you are inside the folder `C:/Path With Spaces` on the file
`C:/Path With Spaces/main.py` and want to re-import some files on
the folder `C:/Path With Spaces/tests`
@param full_module_name the relative full path to the module file
you want to reload from a folder on the
python `sys.path`
"""
import imp
import sys
import importlib
if full_module_name in sys.modules:
module_object = sys.modules[full_module_name]
module_object = imp.reload( module_object )
else:
importlib.import_module( full_module_name )
def run_tests():
print( "\n\n" )
reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" )
reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" )
from .tests import semantic_linefeed_unit_tests
from .tests import semantic_linefeed_manual_tests
semantic_linefeed_unit_tests.run_unit_tests()
semantic_linefeed_manual_tests.run_manual_tests()
if __name__ == "__main__":
run_tests()
如果您第一次运行,这将加载模块,但如果稍后您可以再次运行run_tests()方法/函数,它将重新加载测试文件。对于Sublime Text (Python 3.3.6),这种情况经常发生,因为它的解释器从不关闭(除非你重新启动Sublime Text,即Python3.3解释器)。
2018-02-01
模块foo必须提前导入成功。 从importlib导入重载,重载(foo)
31.5. import - Python 3.6.4文档的实现
重新加载(模块),但前提是它是完全独立的。如果其他任何东西引用了该模块(或属于该模块的任何对象),那么您将会得到一些微妙而奇怪的错误,这些错误是由旧代码存在的时间比您预期的要长,并且像isinstance这样的错误在相同代码的不同版本之间无法工作。
如果有单向依赖关系,还必须重新加载依赖于重新加载的模块的所有模块,以消除对旧代码的所有引用。然后递归地重新加载依赖于重新加载模块的模块。
如果你有循环依赖关系,这是非常常见的,例如当你处理重新加载一个包时,你必须一次性卸载组中的所有模块。使用reload()无法做到这一点,因为它会在刷新依赖项之前重新导入每个模块,从而允许旧的引用渗透到新模块中。
在这种情况下,唯一的方法是入侵sys。模块,这是不受支持的。你必须仔细检查并删除每个系统。您希望在下次导入时重新加载的模块项,还可以删除值为None的项,以处理缓存失败的相对导入的实现问题。这并不是很好,但只要你有一个完全自包含的依赖集,并且不会在代码库之外留下引用,它就是可行的。
最好是重新启动服务器。:-)
使用python3并从importlib重新加载的人。
如果你有问题,比如模块似乎没有重新加载…这是因为它需要一些时间重新编译pyc(最多60秒)。我写这个提示只是想让你知道你是否经历过这种问题。
Enthought Traits有一个模块很好地解决了这个问题。https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html
它将重新加载任何已更改的模块,并更新正在使用它的其他模块和实例对象。它在__very_private__方法的大多数时候都不起作用,并且可能会阻塞类继承,但它为我节省了大量的时间,使我不必在编写PyQt gui或在Maya或Nuke等程序中运行的东西时重新启动主机应用程序。它可能有20% - 30%的时间不起作用,但它仍然非常有帮助。
Enthought的包不会在文件更改时重新加载它们——您必须显式地调用它——但如果您确实需要它,实现它应该不是那么困难