如何在Python中重新加载模块的函数?

65 投票
8 回答
74920 浏览
提问于 2025-04-17 01:05

接着讨论一下关于重新加载一个模块的问题,假如我想从一个已经改变的模块中重新加载一个特定的函数,该怎么做呢?

伪代码:

from foo import bar

if foo.py has changed:
    reload bar

8 个回答

8

热重载在Python中并不是一件简单的事情,搞不好会让你头疼。你实际上不能轻松地实现代码的重载,必须用一些特别的方式来写代码。而且,要想写出能支持重载的代码,还得非常有耐心,这样的代码又复杂得让人觉得不值得去做。测试这些代码也不是一件容易的事。

解决办法是,当代码发生变化时,完全重启Python进程。虽然可以做到无缝重启,但具体怎么做还得看你遇到的具体问题。

89

截至今天,正确的做法是:

import sys, importlib
importlib.reload(sys.modules['foo'])
from foo import bar

在 Python 2.7、3.5 和 3.6 上进行了测试。

15

你想要的确实可以做到,但需要重新加载两个东西……首先是 reload(foo),然后你还得 reload(baz)(假设 baz 是包含 from foo import bar 这条语句的模块名)。

至于为什么……当 foo 第一次加载时,会创建一个 foo 对象,这个对象里面有一个 bar 对象。当你在 baz 模块中导入 bar 时,它会保存一个指向 bar 的引用。当你调用 reload(foo) 时,foo 对象会被清空,然后模块会重新执行。这意味着所有指向 foo 的引用依然有效,但这时会创建一个新的 bar 对象……所以之前导入的所有引用仍然指向的是旧的 bar 对象。通过重新加载 baz,你就会让它重新导入新的 bar


另外,你也可以在你的模块中直接使用 import foo,然后总是调用 foo.bar()。这样每次你 reload(foo) 的时候,都会得到最新的 bar 引用。

注意:从 Python 3 开始,reload 函数需要先导入,方法是 from importlib import reload

撰写回答