Jupyter / Ipython:编写一个模块后,修改不起作用,除非重启内核

Jupyter / IPython: After editing a module, changes are not effective without kernel restart
Jonathan March November 20, 2017 02:37
A powerful feature of Jupyter / IPython (indeed, of Python itself) is that you can interact with your data from the (I)Python command line. In order to provide this functionality, the modules which hold your data remain alive between invocations. Therefore once a module is imported, it stays imported, and re-importing it has no effect at all.
Jupyter / IPython 使得我们可以用一种交互模式操纵数据,为了实现这一功能,模块导入后将持续保持可用,重复导入没有影响

However this great feature can have puzzling consequences, especially to programmers who are more used to compiled languages with make-style dependency change detection. In particular, if you change a python module which has already been imported within ipython, and then re-import that module (e.g. by using ipython to run a program which uses it), python will think “I’ve already imported this module, no need to read that file again”, so your changes will not be effective. (Note that this does not apply to your main program file, which IPython runs directly, rather than importing, so that changes are always effective once they are saved.)
这一功能有时令人困惑,有时你修改了已导入的模块,并且重新导入了这一模块(通过重新运行主程序的方法),Python会认为你已经导入了这个模块,没有必要重新再导入一遍了,所以你对模块的修改并不会起效(但是如果你修改了主程序,会起效的)

There are several ways to work around this issue.

  1. The simplest and most certain is to restart the ipython kernel after changing an imported module. But this has downsides as well, notably losing the data which exists in your ipython namespace and in any other imported modules.
    最简单和确定可行的方法就是重启内核,但这个方法有弊端,尤其是你会丢失已经在你命名空间里的数据和其他已导入模块的数据

  2. For simple cases, you can use python’s reload function. (This function is builtin in Python 2. Starting with Python 3.4, it is imported from standard module “importlib”). In many cases, this suffices after editing a module. It is described briefly in this discussion on Stack Overflow and elsewhere online in more detail.
    在简单的案例中,使用 reload 功能,在Python2这是个内建函数,从Python3.4开始,这一功能需从模块importlib中导入; 在许多案例中,这一方法在模块修改后能够满足需求,这在StackOverflow中有更多的细节讨论

    import importlib
    importlib.reload(some_module)

  3. For more complex cases, where reloading the module that you have edited also requires that its dependent/imported modules be reloaded (e.g. because they must be initialized as part of your edited module’s initialization), ipython’s autoreload extension can be useful. See autoreload including the important caveats at the bottom of the page.
    在更复杂的案例中,重载你修改过的模块需要这一模块依赖的、导入的模块也被重载,IPython某些自动重载的插件会很有帮助