在解释器中重新加载(更新)模块文件

13 投票
3 回答
11224 浏览
提问于 2025-04-16 04:20

假设我有一个Python脚本叫做 script.py,我在解释器里输入以下命令来加载它:

import script

然后我通过输入以下命令来执行我的函数:

script.testFunction(testArgument)

到这里一切都很好,但当我修改了 script.py 后,如果我再尝试导入这个脚本,它不会更新。我必须退出解释器,重新启动解释器,然后再导入新版本的脚本,这样它才能正常工作。

那我应该怎么做呢?

3 个回答

1

我找到的一个替代方案对我帮助很大,就是保持一份 sys.modules 的键的副本,然后在导入新模块后把它们移除,这样可以强制重新导入深层模块:

>>> oldmods = set(sys.modules.keys())
>>> import script
>>> # Do stuff
>>> for mod in set(sys.modules.keys()).difference(oldmods): sys.modules.pop(mod)
>>> import script
7

http://docs.python.org/library/functions.html#reload

reload(module)

这个函数可以重新加载之前导入的模块。你传入的参数必须是一个模块对象,也就是说这个模块之前必须已经成功导入过。这个功能特别有用,比如你用外部编辑器修改了模块的源文件,想在不退出Python解释器的情况下测试新版本。这个函数的返回值是模块对象,也就是你传入的那个模块。

11

你可以发出一个 reload script 的命令,但这不会更新你已经存在的对象,也不会深入到其他模块里去。

幸运的是,IPython 解决了这个问题——它是一个更好的 Python 交互环境,支持自动重载。

要在 IPython 中使用自动重载,你需要先输入 import ipy_autoreload,或者把它永久放在你的 ~/.ipython/ipy_user_conf.py 文件里。

然后运行:

%autoreload 1
%aimport script

%autoreload 1 的意思是,每个用 %aimport 加载的模块在执行提示符中的代码之前都会被重新加载。不过,这不会更新任何已经存在的对象。

想了解更多有趣的功能,可以查看 http://ipython.org/ipython-doc/dev/config/extensions/autoreload.html

撰写回答