我有一个长期运行的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不会在重载时重新计算子模块地址,如果它在sys.modules中
这里有一个变通办法,虽然不完美,但有效。
# Created by BaiJiFeiLong@gmail.com at 2022/2/19 18:50
import importlib
import types
import urllib.parse
import urllib.request
def reloadModuleWithChildren(mod):
mod = importlib.reload(mod)
for k, v in mod.__dict__.items():
if isinstance(v, types.ModuleType):
setattr(mod, k, importlib.import_module(v.__name__))
fakeParse = types.ModuleType("urllib.parse")
realParse = urllib.parse
urllib.parse = fakeParse
assert urllib.parse is fakeParse
importlib.reload(urllib)
assert urllib.parse is fakeParse
assert getattr(urllib, "parse") is fakeParse
reloadModuleWithChildren(urllib)
assert urllib.parse is not fakeParse
assert urllib.parse is realParse
其他回答
下面的代码允许你兼容Python 2/3:
try:
reload
except NameError:
# Python 3
from imp import reload
你可以在两个版本中使用它作为reload(),这让事情变得更简单。
在Python 3.0-3.3中,您将使用:
BDFL已经回答了这个问题。
然而,imp在3.4中被弃用了,取而代之的是importlib(谢谢@Stefan!)
因此,我认为您现在应该使用importlib.reload(module),尽管我不确定。
对于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)
对于像我这样想卸载所有模块的人(当在Emacs下的Python解释器中运行时):
for mod in sys.modules.values():
reload(mod)
更多信息请参见重新加载Python模块。
接受的答案不处理from X import Y的情况。这段代码处理了它和标准的导入情况:
def importOrReload(module_name, *names):
import sys
if module_name in sys.modules:
reload(sys.modules[module_name])
else:
__import__(module_name, fromlist=names)
for name in names:
globals()[name] = getattr(sys.modules[module_name], name)
# use instead of: from dfly_parser import parseMessages
importOrReload("dfly_parser", "parseMessages")
在重新加载的情况下,我们将顶级名称重新分配给新加载的模块中存储的值,从而更新这些值。