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

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

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


当前回答

任何子对象都不会被重载,我相信你必须使用IPython的deepreload。

其他回答

在你的模块导入之前,包括这些行,其中第一个测试是否已经加载了自动加载扩展:

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

import sys
    .
    .
    .

这个怎么样:

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(我认为)中,这样每次你启动解释器时都会加载它。

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

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")

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配置文件create。或者文件可能位于$IPYTHONDIR。