如何卸载(重装)Python模块?

2022-09-05 01:09:30

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

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

答案 1

当模块已经使用 importlib.reload() 导入时,您可以重新加载该模块:

from importlib import reload  # Python 3.4+
import foo

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

在Python 2中,reload是一个内置的。在Python 3中,它被移动到imp模块。在 3.4 中,被弃用以支持 importlib。当以 3 或更高版本为目标时,请在调用或导入模块时引用相应的模块。impreload

我认为这是你想要的。像Django的开发服务器这样的Web服务器使用它,这样你就可以看到代码更改的影响,而无需重新启动服务器进程本身。

引用文档:

  • Python模块的代码被重新编译并重新执行模块级代码,通过重用最初加载模块的加载程序来定义一组绑定到模块字典中名称的新对象。扩展模块的功能不会再次调用。init
  • 与Python中的所有其他对象一样,旧对象仅在其引用计数降至零后才会被回收。
  • 模块命名空间中的名称将更新为指向任何新的或已更改的对象。
  • 对旧对象的其他引用(例如模块外部的名称)不会反弹以引用新对象,并且如果需要,必须在每个命名空间中更新它们。

正如您在问题中指出的那样,如果类驻留在模块中,则必须重建对象。FooFoofoo


答案 2

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

BDFL已经回答了这个问题。

但是,imp 在 3.4 中被弃用,取而代之的是 importlib(感谢 @Stefan!)。

因此,我认为您现在可以使用importlib.reload(module),尽管我不确定。