如何卸载(重新加载)Python模块?

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

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

您可以在Python 2中使用reload builtin函数导入模块时重新加载模块:

import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

在Python 3中, reload被移至imp模块。 在3.4中, imp被赞成importlib而被弃用,并且后者被reload 。 定位3或更高版本时,请在调用reload或导入时引用适当的模块。

我认为这是你想要的。 像Django的开发服务器这样的Web服务器使用它,以便您可以在不重新启动服务器进程本身的情况下看到代码更改的效果。

引用文档:

重新编译Python模块的代码并重新执行模块级代码,定义一组绑定到模块字典中名称的新对象。 扩展模块的初始化函数不是第二次调用。 与Python中的所有其他对象一样,旧对象只有在其引用计数降至零后才会回收。 模块名称空间中的名称将更新为指向任何新的或更改的对象。 对旧对象的其他引用(例如模块外部的名称)不会反弹以引用新对象,并且如果需要,则必须在它们出现的每个命名空间中进行更新。

正如你在你的问题中提到的那样,如果Foo类驻留在foo模块中,你将不得不重构Foo对象。


在Python 3.0-3.3中,您可以使用: imp.reload(module)

BDFL已经回答了这个问题。

但是, imp在3.4中被弃用,赞成importlib (谢谢@Stefan!)。

因此,我认为你现在使用importlib.reload(module) ,但我不确定。


如果模块不是纯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()函数的工件。

链接地址: http://www.djcxy.com/p/56493.html

上一篇: How do I unload (reload) a Python module?

下一篇: Swift: Split a String into an array