在 IPython 中重新加载子模块

发布于 2024-10-25 09:06:48 字数 413 浏览 8 评论 0原文

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

在 IPython 中,框架是通过简单的 import 命令加载的。然而,通常需要更改框架子模块之一中的代码。此时模型已加载,我使用 IPython 与其交互。

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

Currently I am working on a python project that contains sub modules and uses numpy/scipy. Ipython is used as interactive console. Unfortunately I am not very happy with workflow that I am using right now, I would appreciate some advice.

In IPython, the framework is loaded by a simple import command. However, it is often necessary to change code in one of the submodules of the framework. At this point a model is already loaded and I use IPython to interact with it.

Now, the framework contains many modules that depend on each other, i.e. when the framework is initially loaded the main module is importing and configuring the submodules. The changes to the code are only executed if the module is reloaded using reload(main_mod.sub_mod). This is cumbersome as I need to reload all changed modules individually using the full path. It would be very convenient if reload(main_module) would also reload all sub modules, but without reloading numpy/scipy..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

南巷近海 2024-11-01 09:06:48

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。< /em>

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

IPython comes with some automatic reloading magic:

%load_ext autoreload
%autoreload 2

It will reload all changed modules every time before executing a new line. The way this works is slightly different than dreload. Some caveats apply, type %autoreload? to see what can go wrong.


If you want to always enable this settings, modify your IPython configuration file ~/.ipython/profile_default/ipython_config.py[1] and appending:

c.InteractiveShellApp.extensions = ['autoreload']     
c.InteractiveShellApp.exec_lines = ['%autoreload 2']

Credit to @Kos via a comment below.

[1]
If you don't have the file ~/.ipython/profile_default/ipython_config.py, you need to call ipython profile create first. Or the file may be located at $IPYTHONDIR.

情绪操控生活 2024-11-01 09:06:48

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

import importlib
importlib.reload(my_module)

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

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

我建议阅读 importlib.reload() 获取此函数的所有注意事项的列表(递归重新加载、保留旧对象定义的情况等)。

Module named importlib allow to access to import internals. Especially, it provide function importlib.reload():

import importlib
importlib.reload(my_module)

In contrary of %autoreload, importlib.reload() also reset global variables set in module. In most cases, it is what you want.

importlib is only available since Python 3.1. For older version, you have to use module imp.

I suggest to read documentation of importlib.reload() to get the list of all caveats of this function (recursive reload, cases where definitions of old objects remain, etc...).

誰認得朕 2024-11-01 09:06:48

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

%load_ext autoreload
%autoreload 2

这与 pv. 的答案基本相同,只不过扩展已被重命名并且现在使用 %load_ext 加载。

In IPython 0.12 (and possibly earlier), you can use this:

%load_ext autoreload
%autoreload 2

This is essentially the same as the answer by pv., except that the extension has been renamed and is now loaded using %load_ext.

忘你却要生生世世 2024-11-01 09:06:48

由于某种原因,当您将代码从一个笔记本导入到另一个笔记本。仅普通 Python reload 有效:

reload(module)

基于 [1]

For some reason, neither %autoreload, nor dreload seem to work for the situation when you import code from one notebook to another. Only plain Python reload works:

reload(module)

Based on [1].

只怪假的太真实 2024-11-01 09:06:48

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

IPython offers dreload() to recursively reload all submodules. Personally, I prefer to use the %run() magic command (though it does not perform a deep reload, as pointed out by John Salvatier in the comments).

魔法唧唧 2024-11-01 09:06:48

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

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

To avoid typing those magic function again and again, they could be put in the ipython startup script(Name it with .py suffix under .ipython/profile_default/startup. All python scripts under that folder will be loaded according to lexical order), which looks like the following:

from IPython import get_ipython
ipython = get_ipython()

ipython.magic("pylab")
ipython.magic("load_ext autoreload")
ipython.magic("autoreload 2")
裸钻 2024-11-01 09:06:48

怎么样:

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

How about this:

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

This should effectively reload the entire tree of modules and submodules you give it. You can also put this function in your .ipythonrc (I think) so it is loaded every time you start the interpreter.

趁年轻赶紧闹 2024-11-01 09:06:48

我重新加载的标准做法是在首次打开 IPython 后结合使用这两种方法:

from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2

在执行此操作之前加载模块将导致它们无法重新加载,即使使用手动重新加载(模块名称)也是如此>。我仍然很少遇到类方法未重新加载的莫名其妙的问题,而我还没有研究过。

My standard practice for reloading is to combine both methods following first opening of IPython:

from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2

Loading modules before doing this will cause them not to be reloaded, even with a manual reload(module_name). I still, very rarely, get inexplicable problems with class methods not reloading that I've not yet looked into.

江城子 2024-11-01 09:06:48

另一种选择:

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

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

Another option:

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

Verified on ipython and ipython3 v5.1.0 on Ubuntu 14.04.

川水往事 2024-11-01 09:06:48

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

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

import sys
    .
    .
    .

Prior to your module imports include these lines, where the first tests whether or not the autoreload extension has already been loaded:

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

import sys
    .
    .
    .
看春风乍起 2024-11-01 09:06:48

我讨厌在长线程中添加另一个答案,但我找到了一个解决方案,可以在 %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

I hate to add yet another answer to a long thread, but I found a solution that enables recursive reloading of submodules on %run() that others might find useful (I have anyway)

del the submodule you wish to reload on run from sys.modules in iPython:

In[1]: from sys import modules
In[2]: del modules["mymodule.mysubmodule"] # tab completion can be used like mymodule.<tab>!

Now your script will recursively reload this submodule:

In[3]: %run myscript.py
喜爱纠缠 2024-11-01 09:06:48

请注意,如果您手动保存更改的文件(例如使用 ctrl+s 或 cmd+s),上面提到的 autoreload 仅适用于 IntelliJ。它似乎不适用于自动保存。

Note that the above mentioned autoreload only works in IntelliJ if you manually save the changed file (e.g. using ctrl+s or cmd+s). It doesn't seem to work with auto-saving.

转角预定愛 2024-11-01 09:06:48

在 Anaconda 上的 Jupyter Notebooks 上,执行以下操作:

%load_ext autoreload
%autoreload 2

生成消息:

自动重新加载扩展已加载。要重新加载它,请使用:
%reload_ext 自动重载

看起来最好这样做:

%reload_ext autoreload
%autoreload 2

版本信息:

笔记本服务器的版本是 5.0.0,运行于:
Python 3.6.2 |Anaconda 公司| (默认,2017 年 9 月 20 日,13:35:58)[MSC v.1900 32 位(英特尔)]

On Jupyter Notebooks on Anaconda, doing this:

%load_ext autoreload
%autoreload 2

produced the message:

The autoreload extension is already loaded. To reload it, use:
%reload_ext autoreload

It looks like it's preferable to do:

%reload_ext autoreload
%autoreload 2

Version information:

The version of the notebook server is 5.0.0 and is running on:
Python 3.6.2 |Anaconda, Inc.| (default, Sep 20 2017, 13:35:58) [MSC v.1900 32 bit (Intel)]

烟燃烟灭 2024-11-01 09:06:48

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

Any subobjects will not be reloaded by this, I believe you have to use IPython's deepreload for that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文