我如何让 ipython 知道对自写模块所做的更改?

How do I make ipython aware of changes made to a selfwritten module?

尝试自写模块时,很可能在前几次以错误结束。

但是在修复这些错误时,ipython似乎没有注意到。

是否有ipython命令来重新加载新模块? 'clear' 不成功。到目前为止,唯一可行的是 'exit' 并开始一个新会话。但这也意味着重做我到目前为止所做的一切。

或者我是否需要向模块添加一些东西,以便它在 运行 之后杀死所有内部变量?

示例:

from mymodule import readCSVts
import pandas as pd
data = readCSVts('file.csv')

TypeError                                 Traceback (most recent call last)
<ipython-input-158-8f82f1a78260> in <module>()
----> 1 data = readCSVts('file.csv')

/home/me/path/to/mymodule.py in readCSVts(filename)
    194                 Cons_NaNs=hydroTS[(hydroTS.level.isnull())&(hydroTS.level.shift().isnull())&(hydroTS.level.shift(periods=2).isnull())]
    195                 #This is a pandas dataframe containing all rows with NaN
    196                 Cons_NaNs_count = len(Cons_NaNs)
    197                 Cons_NaNs_str = str(Cons_NaNs_count)
    198                 Cons_NaN_Name_joiner = [current_csv,';',Cons_NaNs]
--> 199                 Cons_NaN_Name_str = ''.join(Cons_NaN_Name_joiner)

TypeError: sequence item 2: expected string, DataFrame found

好的,这很简单。我在第 198 行打错了,写了 Cons_NaNs 而不是 Cons_NaNs_str,因此我得到了一个明显的错误,试图用字符串连接数据框。

但是在 mymodule.py 文件中修复它之后,我得到以下(缩短的)错误:

    197                 Cons_NaNs_str = str(Cons_NaNs_count)
    198                 Cons_NaN_Name_joiner = [current_csv,';',Cons_NaNs_str]
--> 199                 Cons_NaN_Name_str = ''.join(Cons_NaN_Name_joiner)

TypeError: sequence item 2: expected string, DataFrame found

查看回溯,ipython 很清楚源文件中进行了更改,它表明我修复了 _str 缺失的拼写错误,但仍然报错, 乍一看似乎是不可能的。在 运行ning clear 并重新导入所有内容后,它显示相同的行为。

因此,为了确保我没有在整个过程中的某个地方犯下愚蠢的错误,我在 ipython 中逐步完成了我的整个模块。使我达到这一点的每个变量都按预期运行。

Cons_NaNs 是数据帧,Cons_NaNs_count 是整数,Cons_NaNs_str 是字符串。

所以我退出 ipython,重新启动它并重新导入所有内容,现在它可以工作了。

但是不得不退出 ipython 很糟糕。大多数时候,这意味着必须重新导入几十个东西并执行几十个命令,才能真正测试我当前正在做的事情。

这不仅适用于 ipython ,而且 Python 通常会在模块首次导入 sys.modules 时缓存该模块。因此,在第一次导入之后,每当您尝试导入它时,您都会从 sys.modules 中获取缓存的模块对象。

要使 Python 重新加载模块对象而不必重新启动 Python,以便反映对模块所做的更改,您应该使用 reload() built-in function (Python 2.x) or importlib.reload() (Python 3.x).

Python 2.x -

<module> = reload(<module>)

例子-

import module
module = reload(module) #This requires the module as it is, not a string.

Python 3.x -

import importlib
<module> = importlib.reload(<module>)

类似于上面的Python 2.x示例,只需使用importlib.reload()而不是reload()

当您终止 IPython notebook 服务器并重新启动它时,您将拥有一个新的内核实例,它不会在您的 notebook 本身中持续存在。 您应该在 运行 所有单元格打开笔记本后立即开始您的工作流程。在顶部菜单中,select "Cell->Run all"

有一个Ipython具体的方法,你可以使用设置autoreload:

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

模块在没有显式重新加载的情况下被重新加载,并且使用 from foo import ... 导入的对象也被更新。

用法 提供了以下魔术命令:

%autoreload

Reload all modules (except those excluded by %aimport) automatically now.

%autoreload 0

Disable automatic reloading.

%autoreload 1

Reload all modules imported with %aimport every time before executing the >Python code typed.

%autoreload 2

Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.

%aimport

List modules which are to be automatically imported or not to be imported.

%aimport foo

Import module ‘foo’ and mark it to be autoreloaded for %autoreload 1

%aimport -foo

Mark module ‘foo’ to not be autoreloaded.

还有 dreload 可用于 python2 和 3.

 dreload(module)