在IPython中重新加载子模块
我现在在做一个Python项目,这个项目里有一些子模块,还用到了numpy和scipy。我在用IPython作为交互式控制台。不过,我对现在的工作流程不是很满意,希望能得到一些建议。
在IPython中,可以通过简单的import
命令来加载框架。但是,有时候我需要修改框架中某个子模块的代码。这个时候,模型已经加载好了,我用IPython和它进行交互。
现在,这个框架里有很多相互依赖的模块,也就是说,当框架最开始加载的时候,主模块会导入并配置这些子模块。如果我对代码进行了修改,只有在使用reload(main_mod.sub_mod)
重新加载模块时,修改才会生效。这就很麻烦,因为我需要逐个使用完整路径重新加载所有修改过的模块。如果reload(main_module)
能同时重新加载所有子模块,但不重新加载numpy和scipy,那就方便多了。
14 个回答
在IPython 0.12版本(可能更早的版本也可以),你可以使用这个:
%load_ext autoreload
%autoreload 2
这基本上和pv给出的答案是一样的,只是这个扩展的名字换了,现在是通过%load_ext
来加载的。
名为 importlib
的模块可以让你访问 Python 的导入内部机制。特别是,它提供了一个函数 importlib.reload()
:
import importlib
importlib.reload(my_module)
与 %autoreload
不同,importlib.reload()
还会重置模块中设置的全局变量。在大多数情况下,这正是你想要的效果。
importlib
从 Python 3.1 开始才可以使用。如果你使用的是更早的版本,就需要用到 imp
模块。
我建议你查看一下 importlib.reload()
的文档,了解这个函数的所有注意事项(比如递归重载、旧对象定义仍然存在的情况等等)。
IPython 有一些很方便的自动重载功能:
%load_ext autoreload
%autoreload 2
每次执行新的一行代码之前,它会自动重新加载所有有改动的模块。这种工作方式和 dreload
有点不同。使用时要注意一些问题,可以输入 %autoreload?
来查看可能出现的错误。
如果你想一直启用这个设置,可以修改你的 IPython 配置文件 ~/.ipython/profile_default/ipython_config.py
[1],并添加以下内容:
c.InteractiveShellApp.extensions = ['autoreload']
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
感谢 @Kos 在下面的评论中提供的信息。
[1] 如果你没有 ~/.ipython/profile_default/ipython_config.py
这个文件,你需要先运行 ipython profile create
来创建它。或者这个文件可能在 $IPYTHONDIR
目录下。