在IPython中重新加载子模块

时间:2011-03-19 18:39:11

标签: python numpy ipython

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

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

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

14 个答案:

答案 0 :(得分:447)

IPython带有一些automatic reloading魔法:

%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

答案 1 :(得分:24)

在IPython 0.12(可能更早)中,您可以使用:

%load_ext autoreload
%autoreload 2

这与pv.的答案基本相同,只是扩展程序已重命名,现在使用%load_ext加载。

答案 2 :(得分:18)

IPython提供dreload()以递归方式重新加载所有子模块。就个人而言,我更喜欢使用%run()魔法命令(尽管它没有执行深度重载,正如John Salvatier在评论中所指出的那样)。

答案 3 :(得分:14)

出于某种原因,当您import code from one notebook to another时,%autoreloaddreload似乎都不适用于这种情况。只有普通的Python reload可以工作:

reload(module)

基于[1]

答案 4 :(得分:3)

这个怎么样:

import inspect

# needs to be primed with an empty set for loaded
def recursively_reload_all_submodules(module, loaded=None):
    for name in dir(module):
        member = getattr(module, name)
        if inspect.ismodule(member) and member not in loaded:
            recursively_reload_all_submodules(member, loaded)
    loaded.add(module)
    reload(module)

import mymodule
recursively_reload_all_submodules(mymodule, set())

这应该有效地重新加载你给它的整个模块和子模块树。您也可以将此函数放在.ipythonrc中(我认为),这样每次启动解释器时都会加载它。

答案 5 :(得分:3)

http://shawnleezx.github.io/blog/2015/08/03/some-notes-on-ipython-startup-script/

为了避免一次又一次地输入这些魔术函数,可以将它们放入ipython启动脚本(在.ipython / profile_default / startup下使用.py后缀命名。该文件夹下的所有python脚本将根据词法顺序加载),如下所示:

from IPython import get_ipython
ipython = get_ipython()

ipython.magic("pylab")
ipython.magic("load_ext autoreload")
ipython.magic("autoreload 2")

答案 6 :(得分:2)

另一种选择:

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

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

答案 7 :(得分:1)

我重新加载的标准做法是在首次打开\1(?<DaysInMonth>\d\s+) (?<FirstTitle>[\w\s \]+)\] (?<SecondTitle>[\w\s \]+)$ 后合并两种方法:

IPython

在执行此操作之前加载模块将导致它们无法重新加载,即使使用手动from IPython.lib.deepreload import reload %load_ext autoreload %autoreload 2 也是如此。我仍然非常罕见地遇到了无法重新加载的类方法的无法解释的问题,而我还没有考虑过。

答案 8 :(得分:1)

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

import importlib
importlib.reload(my_module)

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

importlib仅从Python 3.1开始可用。对于旧版本,您必须使用模块imp

答案 9 :(得分:1)

我讨厌为长线程添加另一个答案,但是我找到了一种解决方案,该解决方案可以在%run()上递归重载子模块,而其他人可能会觉得有用(无论如何)

del您希望在iPython中从sys.modules运行时重新加载的子模块:

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

答案 10 :(得分:0)

在关于Anaconda的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 v.1900 32 bit(Intel)]

答案 11 :(得分:0)

任何子对象都不会由此被重新加载,我相信您必须为此使用IPython的deepreload。

答案 12 :(得分:0)

请注意,上述autoreload仅在您手动保存更改的文件(例如,使用ctrl + s或cmd + s)时才能在IntelliJ中使用。自动保存似乎不起作用。

答案 13 :(得分:0)

在您的模块导入之前包括这些行,其中第一行测试是否已加载 autoreload 扩展:

if 'autoreload' not in get_ipython().extension_manager.loaded:
    %load_ext autoreload
%autoreload 2

import sys
    .
    .
    .