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

21 浏览
0 Comments

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

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

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

admin 更改状态以发布 2023年5月22日
0
0 Comments

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

BDFL已经回答了这个问题(参见这里)。

然而,在3.4中,imp被弃用,支持importlib(感谢@Stefan!)。

因此,我认为现在需要使用importlib.reload(module),虽然我不太确定。

0
0 Comments

当一个模块已经被导入后,你可以使用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中,imp弃用,推荐使用importlib。如果要针对3或更高的版本,调用reload时请引用适当的模块或者直接导入它。

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

引用文档中的原话:

  • Python模块的代码被重新编译,模块级别的代码被重新执行,定义了一组新的对象,这些对象通过重用最初加载模块的loader绑定到模块的字典中的名称。扩展模块的init函数不会被第二次调用。
  • 与Python中的所有其他对象一样,只有当引用计数降至零时,旧对象才会被回收。
  • 模块命名空间中的名称被更新以指向任何新的或更改的对象。
  • 不会重新绑定到新对象的旧对象的其他引用(例如外部名称)必须在它们出现的每个命名空间中更新,如果需要的话。

正如你在问题中指出的那样,如果Foo类位于foo模块中,你将不得不重构Foo对象。

0