在修改一些模块后,在Jupyter里import并没有生效, 如何解决?

问题情景

比如我们写一个help.py文件,里面有个load_data函数,我们在Jupyter里写import helper,然后调用load_data函数,Run。

此时在修改load_data函数,然后再Run,发现调用的依然是修改之前的load_data函数,如何让我们的修改生效呢?

解决方法

  1. 最简单:直接重启Kernel,然后在Run;
  2. 简单: 使用Python的reload函数,该函数在python2中是builtin函数,从Python3.4开始,移到importlib下面,用法如下: ```python
    easy case
    import X

    modify X outside

    reload it

    reload(X) # python2 import importlib # python3.4 or after importlib.reload(X)
complicated case

from Y import X

reload(X) # it works only when Y is module and X is a package, otherwise it's wrong

所以不要轻易的去import 类,函数,而是import 一个模块。见参考链接3。

此种方法不仅在Jupyter适用,在写python的时候也适用,只不过一般在`py`文件调用的时候,外部会生成`pyc`文件,把`pyc`文件删掉,不需要调用`reload`函数,
系统也会自动`reload`,因为他会检查是否有`pyc`文件,没有`pyc`文件,会重新生成一个。关于`pyc`文件是什么,可以看参考链接4.

3. 复杂: 使用IPython提供的`autoreload`
Usage:
```IPython
In [1]: %load_ext autoreload

In [2]: %autoreload 2

In [3]: from foo import some_function

In [4]: some_function()
Out[4]: 42

In [5]: # open foo.py in an editor and change some_function to return 43

In [6]: some_function()
Out[6]: 43

autoreload 有好几种模式:

- `autoreload 0`:Disable automatic reloading;
- `autoreload 1`:在执行代码前只reload所有由`%aimport`的模块;
- `autoreload 2`:在执行代码前只reload所有不是由`%aimport`的模块;

%aimport的用法

- %aimport foo: Import module ‘foo’ and mark it to be autoreloaded for `%autoreload 1`;
- %aimport foo, bar: Import modules ‘foo’, ‘bar’ and mark them to be autoreloaded for `%autoreload 1`;
- %aimport -foo: Mark module ‘foo’ to not be autoreloaded.

参考资料:

  1. Jupyter / IPython: After editing a module, changes are not effective without kernel restart
  2. autoreload

  3. Python: reload component Y imported with 'from X import Y'?

  4. Python什么情况下会生成pyc文件?

results matching ""

    No results matching ""