在修改一些模块后,在Jupyter里import并没有生效, 如何解决?
问题情景
比如我们写一个help.py文件,里面有个load_data
函数,我们在Jupyter里写import helper
,然后调用load_data
函数,Run。
此时在修改load_data
函数,然后再Run,发现调用的依然是修改之前的load_data
函数,如何让我们的修改生效呢?
解决方法
- 最简单:直接重启Kernel,然后在Run;
- 简单: 使用Python的reload函数,该函数在python2中是builtin函数,从Python3.4开始,移到importlib下面,用法如下:
```python
easy case
import Xmodify 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.
参考资料: