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

新手上路,请多包涵

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

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

原文由 Mark Harrison 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 345
2 个回答

您可以使用 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 模块的代码并重新执行模块级代码,通过重用最初加载模块的 加载器 定义一组新的对象,这些对象绑定到模块字典中的名称。扩展模块的 init 函数没有被二次调用。
  • 与 Python 中的所有其他对象一样,旧对象仅在其引用计数降至零后才会被回收。
  • 模块命名空间中的名称被更新为指向任何新的或更改的对象。
  • 对旧对象的其他引用(例如模块外部的名称)不会重新绑定以引用新对象,并且如果需要,必须在它们出现的每个命名空间中进行更新。

正如您在问题中指出的那样,如果 Foo 类位于 foo 模块中,则必须重建 Foo 对象。

原文由 cdleary 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题