如何强制ipython进行深层换料?

2024-05-12 05:57:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我在ipython中通过run magic运行一个脚本:

%run myscript.py

这个脚本导入了我编写的各种模块,我经常在运行期间更改这些模块。我想自动重新加载这些模块,而不是重新启动ipython。在stackoverflow和其他地方有很多问题可以推荐

^{pr2}$

也许还有

 %aimport <your module>

以适当的方式投进去。但这根本行不通。深度加载是否超出了autoreload的能力?是否有其他方法可以删除所有加载的模块,或者静默地重新启动ipython所依赖的python后台进程?在

编辑:在玩了一点这个,似乎自动转载失败是一个更微妙的。可能(我还不是百分之百确定)autoreload只有在我的模块的{}执行from .<some file in the module> import *时才会失败,而不是按名称导入每个成员。我也尝试过%reset魔术,但这只会清空名称空间,不会清除缓存的模块。在

顺便说一句,Spyder可以强制重新加载模块,但我不确定这是如何实现的(某种ipython的包装器,它可以重新启动进程?)在


Tags: 模块runpy脚本名称进程地方magic
1条回答
网友
1楼 · 发布于 2024-05-12 05:57:13

我查阅了Spyder的解决方案,它基本上是在sys.modules上使用del。下面我稍微修改了~/anaconda3/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py中找到的代码,并将其放入名为reloader.py的模块中:

import sys


def _is_module_deletable(modname, modpath):
    if modname.startswith('_cython_inline'):
        # Don't return cached inline compiled .PYX files
        return False
    for path in [sys.prefix]:
        if modpath.startswith(path):
            return False
    else:
        return set(modname.split('.'))


def clear():
    """
    Del user modules to force Python to deeply reload them

    Do not del modules which are considered as system modules, i.e.
    modules installed in subdirectories of Python interpreter's binary
    Do not del C modules
    """
    log = []
    for modname, module in list(sys.modules.items()):
        modpath = getattr(module, '__file__', None)

        if modpath is None:
            # *module* is a C module that is statically linked into the
            # interpreter. There is no way to know its path, so we
            # choose to ignore it.
            continue

        if modname == 'reloader':
            # skip this module
            continue

        modules_to_delete = _is_module_deletable(modname, modpath)
        if modules_to_delete:
            log.append(modname)
            del sys.modules[modname]

    print("Reloaded modules:\n\n%s" % ", ".join(log))

现在只需执行import reloader,然后调用reloader.clear()

相关问题 更多 >