目前我正在开发一个包含子模块并使用numpy / scipy的python项目。 Ipython用作交互式控制台。不幸的是,我对我现在使用的工作流程不是很满意,我很感激一些建议。
在IPython中,框架由简单的import
命令加载。但是,通常需要更改框架的一个子模块中的代码。此时已经加载了一个模型,我使用IPython与它进行交互。
现在,框架包含许多相互依赖的模块,即在最初加载框架时,主模块正在导入和配置子模块。只有在使用reload(main_mod.sub_mod)
重新加载模块时才会执行对代码的更改。这很麻烦,因为我需要使用完整路径单独重新加载所有已更改的模块。如果reload(main_module)
也会重新加载所有子模块,但没有重新加载numpy / scipy,那将是非常方便的。
答案 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)
答案 3 :(得分:14)
出于某种原因,当您import code from one notebook to another时,%autoreload
和dreload
似乎都不适用于这种情况。只有普通的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
.
.
.