问题:在IPython中重新加载子模块
目前,我正在处理一个包含子模块并使用numpy / scipy的python项目。Ipython用作交互式控制台。不幸的是,我对现在使用的工作流程不是很满意,请多多指教。
在IPython中,该框架是通过一个简单的import
命令加载的。但是,通常有必要在框架的子模块之一中更改代码。至此,已经加载了一个模型,并且我使用IPython与之交互。
现在,该框架包含许多相互依赖的模块,即,在最初加载该框架时,主模块正在导入和配置子模块。仅当使用重新加载模块时,才执行对代码的更改reload(main_mod.sub_mod)
。这很麻烦,因为我需要使用完整路径分别重新加载所有更改的模块。如果reload(main_module)
还重新加载所有子模块,但又不重新加载numpy / scipy ,将非常方便。
回答 0
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
。
回答 1
在IPython 0.12(可能更早)中,您可以使用以下命令:
%load_ext autoreload
%autoreload 2
回答 2
由于某种原因,当您将代码从一个笔记本导入另一个笔记本时,这两种方法都不起作用%autoreload
,也dreload
似乎不起作用。只有普通的Python 可以工作:reload
reload(module)
基于[1]。
回答 3
IPython提供dreload()
了递归方式重新加载所有子模块。就个人而言,我更喜欢使用%run()
magic命令(尽管它不会执行深度重新加载,正如John Salvatier在评论中指出的那样)。
回答 4
名为importlib
allow的模块可以访问导入内部构件。特别是,它提供功能importlib.reload()
:
import importlib
importlib.reload(my_module)
与此相反%autoreload
,importlib.reload()
还重置模块中设置的全局变量。在大多数情况下,这就是您想要的。
importlib
仅从Python 3.1开始可用。对于旧版本,您必须使用module imp
。
回答 5
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
这个怎么样:
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中(我认为),以便每次启动解释器时都将其加载。
回答 7
另外一个选项:
$ cat << EOF > ~/.ipython/profile_default/startup/50-autoreload.ipy
%load_ext autoreload
%autoreload 2
EOF
在Ubuntu 14.04上的ipython和ipython3 v5.1.0上进行了验证。
回答 8
我的重载标准做法是在首次打开时将两种方法结合起来IPython
:
from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2
在执行此操作之前加载模块将导致即使使用手册也无法重新加载它们reload(module_name)
。我仍然很少遇到类方法无法重装的莫名其妙的问题,而我尚未研究过。
回答 9
请注意,autoreload
如果您手动保存更改的文件(例如,使用ctrl + s或cmd + s),则上述内容仅在IntelliJ中有效。自动保存似乎不起作用。
回答 10
在Anaconda的Jupyter笔记本上,执行以下操作:
%load_ext autoreload
%autoreload 2
产生了消息:
autoreload扩展程序已加载。要重新加载它,请使用:
%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位(Intel)]
回答 11
此操作将不会重新加载任何子对象,我相信您必须为此使用IPython的deepreload。