如何强制ipython深度重载?

时间:2018-03-15 12:04:31

标签: python ipython

我正在通过运行魔法在ipython中运行脚本:

%run myscript.py

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

%load_ext autoreload
%autoreload 2

也许

 %aimport <your module>

投入了很好的措施。但这根本行不通。是否超出了autoreload能够做的深度重载?是否有其他方法可以删除所有已加载的模块,或者以静默方式重启ipython所依赖的python后台进程?

编辑:多玩了一下,似乎自动重载失败更加微妙。可能是(我还不是100%确定)当我的模块的__init__.py正在执行from .<some file in the module> import *时,自动重载只会失败,而不是按名称导入每个成员。我也尝试了%reset魔术,但这只是为了清空命名空间,它不会清除缓存的模块。

顺便说一下,Spyder能够强制重新加载模块,但是我不确定这是怎么做的(ipython的某种包装会重启这个过程吗?)

1 个答案:

答案 0 :(得分:2)

我查找了Spyder的解决方案,它基本上使用了for(var i = 0; i < analyteNames.Length; i++) { dt.Rows.Add(analyteNames[i], units[i], values[i]); } 上的del。下面我稍微修改了我在sys.modules中找到的代码,并将其放在名为~/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