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

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

当前回答

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

其他回答

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

首先,确保您使用的是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.

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

如果一个模块不是纯Python的,那么删除它会特别困难。

下面是来自:如何真正删除导入的模块?

您可以使用sys.getrefcount()来找出的实际数量 参考文献

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

大于3的数字表示 它将很难摆脱 模块。本土的“空” (不包含任何内容)模块应该 垃圾收集后

>>> del sys.modules["empty"]
>>> del empty

因为第三个参考是一个人工制品 getrefcount()函数的。

Enthought Traits有一个模块很好地解决了这个问题。https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html

它将重新加载任何已更改的模块,并更新正在使用它的其他模块和实例对象。它在__very_private__方法的大多数时候都不起作用,并且可能会阻塞类继承,但它为我节省了大量的时间,使我不必在编写PyQt gui或在Maya或Nuke等程序中运行的东西时重新启动主机应用程序。它可能有20% - 30%的时间不起作用,但它仍然非常有帮助。

Enthought的包不会在文件更改时重新加载它们——您必须显式地调用它——但如果您确实需要它,实现它应该不是那么困难

从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 2/3:

try:
    reload
except NameError:
    # Python 3
    from imp import reload

你可以在两个版本中使用它作为reload(),这让事情变得更简单。