目前,我正在研究一个包含子模块的python项目,并使用numpy/scipy。使用Ipython作为交互控制台。不幸的是,我对我现在使用的工作流程不是很满意,我很感激一些建议。

在IPython中,框架是通过一个简单的导入命令加载的。但是,经常需要更改框架的一个子模块中的代码。此时,已经加载了一个模型,我使用IPython与它交互。

现在,框架包含许多相互依赖的模块,也就是说,当框架最初加载时,主模块正在导入和配置子模块。只有使用reload(main_mod.sub_mod)重新加载模块时,才会执行对代码的更改。这很麻烦,因为我需要使用完整的路径单独重新加载所有更改的模块。如果reload(main_module)也会重载所有子模块,但不重载numpy/scipy..


当前回答

我讨厌为一个长线程添加另一个答案,但我发现了一个解决方案,它支持在%run()上递归重新加载子模块,其他人可能会发现这很有用(反正我有)

删除你想要重载的子模块。iPython中的模块:

In[1]: from sys import modules
In[2]: del modules["mymodule.mysubmodule"] # tab completion can be used like mymodule.<tab>!

现在你的脚本将递归重载这个子模块:

In[3]: %run myscript.py

其他回答

另一个选择:

$ cat << EOF > ~/.ipython/profile_default/startup/50-autoreload.ipy
%load_ext autoreload
%autoreload 2
EOF

已在Ubuntu 14.04的ipython和ipython3 v5.1.0上验证。

我重新加载的标准做法是在第一次打开IPython后结合这两种方法:

from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2

在此之前加载模块将导致它们不会被重新加载,即使使用手动重新加载(module_name)。我仍然很少遇到类方法不能重新加载的难以解释的问题,我还没有深入研究。

在阿纳康达的Jupyter笔记本上,这样做:

%load_ext autoreload
%autoreload 2

产生的消息:

自动重载扩展已经加载。要重新加载,请使用: % reload_ext autoreload

看起来更可取的做法是:

%reload_ext autoreload
%autoreload 2

版本信息:

笔记本服务器的版本是5.0.0并且正在运行: Python 3.6.2 |Anaconda, Inc.|(默认,2017年9月20日,13:35:58)[MSC .1900 32位(英特尔)]

名为importlib的模块允许访问导入内部。特别是,它提供了importlib.reload()函数:

import importlib
importlib.reload(my_module)

与%autoreload相反,importlib.reload()也会重置模块中设置的全局变量。在大多数情况下,这就是你想要的。

importlib仅在Python 3.1之后可用。对于旧版本,您必须使用模块imp。

我建议阅读importlib.reload()的文档,以获得此函数的所有警告列表(递归重载,保留旧对象定义的情况,等等……)

在IPython 0.12(可能更早)中,你可以使用这个:

%load_ext autoreload
%autoreload 2

这本质上和除以pv的结果是一样的。,除了扩展名已经重命名并且现在使用%load_ext加载。