在IPython中重新加载子模块

Ala*_*ain 329 python ipython

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

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

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

pv.*_*pv. 477

IPython带有一些自动重装魔法:

%load_ext autoreload
%autoreload 2
Run Code Online (Sandbox Code Playgroud)

它会在执行新行之前每次重新加载所有已更改的模块.这种方式的工作方式略有不同dreload.一些警告适用,键入%autoreload?以查看可能出错的地方.


如果要始终启用此设置,请修改IPython配置文件~/.ipython/profile_default/ipython_config.py[1]并附加:

c.InteractiveShellApp.extensions = ['autoreload']     
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
Run Code Online (Sandbox Code Playgroud)

通过以下评论获得@Kos.

[1]如果您没有该文件~/.ipython/profile_default/ipython_config.py,则需要先拨打电话ipython profile create.或者文件可能位于$IPYTHONDIR.

  • 我在`〜/ .ipython/profile_default/ipython_config.py`中有`c.InteractiveShellApp.extensions = ['autoreload']`和`c.InteractiveShellApp.exec_lines = ['%autoreload 2']`. (60认同)
  • 但这可能会影响性能,因此请谨慎使用. (4认同)
  • 你如何永久地做出这些改变? (3认同)
  • 只有在Ipython shell中按Enter键才会执行重新加载,而且通常不会引人注意. (3认同)
  • 这在调试包时非常好用,所以dreload的目的是什么,似乎dreload太具侵略性并且在加载像matplotlib这样的包时会输出错误. (3认同)
  • 如果使用@Kos方法,请确保定义了c:c = get_config() (3认同)

Raf*_*afG 26

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

%load_ext autoreload
%autoreload 2
Run Code Online (Sandbox Code Playgroud)

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


Jér*_*ler 20

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

import importlib
importlib.reload(my_module)
Run Code Online (Sandbox Code Playgroud)

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

importlib仅自 Python 3.1 起可用。对于旧版本,您必须使用 module imp

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

  • 在过去的两年里,我多次用谷歌搜索这个问题,每次你的答案都是我正在寻找的完美答案。谢谢。 (18认同)

Sve*_*ach 18

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

  • 我认为(不幸的是)%run script.py只重新加载你正在调用的脚本,而不是它导入的包.如果您正在尝试调试正在构建的程序包,这可能会很麻烦. (11认同)
  • NB.`dreload`已经被[deepreload](http://ipython.readthedocs.io/en/stable/api/generated/IPython.lib.deepreload.html)替换为最近的IPython(例如IPython 6.0). (2认同)

Den*_*zov 17

出于某种原因,没有%autoreload,也不dreload似乎对于这种情况,当你的工作从一台笔记本电脑导入代码到另一个.只有普通的Python reload工作:

reload(module)
Run Code Online (Sandbox Code Playgroud)

基于[1].

  • 在Python 3.4+中,您可以在importlib模块中找到重新加载.见[这个问题](/sf/answers/1917146941/). (9认同)

Y.H*_*ong 5

这个怎么样:

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())
Run Code Online (Sandbox Code Playgroud)

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


Peg*_*sus 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")
Run Code Online (Sandbox Code Playgroud)