我有一个长期运行的Python服务器,希望能够在不重新启动服务器的情况下升级服务。最好的方法是什么?

if foo.py has changed:
    unimport foo  <-- How do I do this?
    import foo
    myfoo = foo.Foo()

当前回答

其他选项。请参阅Python默认importlib。Reload将只是重新导入作为参数传递的库。它不会重新加载库导入的库。如果您更改了很多文件,并且有一个有点复杂的包要导入,那么您必须进行深度重载。

如果你安装了IPython或Jupyter,你可以使用一个函数来深度重载所有库:

from IPython.lib.deepreload import reload as dreload
dreload(foo)

如果你没有Jupyter,在你的shell中使用以下命令安装它:

pip3 install jupyter

其他回答

对于像我这样想卸载所有模块的人(当在Emacs下的Python解释器中运行时):

   for mod in sys.modules.values():
      reload(mod)

更多信息请参见重新加载Python模块。

从sys. exe中移除模块。modules也需要删除'None'类型。

方法1:

import sys
import json  ##  your module

for mod in [ m for m in sys.modules if m.lstrip('_').startswith('json') or sys.modules[m] == None ]: del sys.modules[mod]

print( json.dumps( [1] ) )  ##  test if functionality has been removed

方法2,使用簿记条目,删除所有依赖项:

import sys

before_import = [mod for mod in sys.modules]
import json  ##  your module
after_import = [mod for mod in sys.modules if mod not in before_import]

for mod in [m for m in sys.modules if m in after_import or sys.modules[m] == None]: del sys.modules[mod]

print( json.dumps( [2] ) )  ##  test if functionality has been removed

可选的,只是为了确保所有的条目都出来了,如果你这样选择:

import gc
gc.collect()

另一种方法是在函数中导入模块。这样,当函数完成时,模块就会被垃圾收集。

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

如果你不在服务器上,但正在开发,需要频繁地重新加载一个模块,这里有一个不错的技巧。

首先,确保您使用的是Jupyter Notebook项目中的优秀IPython shell。在安装Jupyter之后,您可以使用ipython或Jupyter控制台启动它,甚至更好的是Jupyter qtconsole,这将为您提供一个在任何操作系统中都具有代码完成功能的漂亮的彩色控制台。

现在在shell中输入:

%load_ext autoreload
%autoreload 2

现在,每次运行脚本时,模块都会被重新加载。

除了2,还有其他自动重载魔法的选项:

%autoreload
Reload all modules (except those excluded by %aimport) automatically now.

%autoreload 0
Disable automatic reloading.

%autoreload 1
Reload all modules imported with %aimport every time before executing the Python code typed.

%autoreload 2
Reload all modules (except those excluded by %aimport) every time before
executing the Python code typed.

当然,它也可以在木星笔记本上工作。