2015-08-28 21 views
5

嘗試使用自寫模塊時,最初幾次可能會以錯誤結束。如何讓ipython意識到對自寫模塊所做的更改?

但是當修復這些錯誤時,ipython似乎沒有注意到這一點。

是否有一個ipython命令來重新加載新模塊? '明確'並不能解決問題。到目前爲止,唯一可行的是「退出」並開始新的會話。但這也意味着重做我到目前爲止所做的一切。

或者我需要添加一些東西到模塊,它會殺死所有的內部變量運行後?

例子:

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 

OK,這很容易。我在第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的錯字,但它仍然給出了一個錯誤,在第一眼看來似乎是不可能的。運行clear並重新導入所有內容後,它會顯示相同的行爲。

所以,爲了確保我沒有在某個地方犯下一個愚蠢的錯誤,我在ipython中一步一步地去了整個模塊。而每一個引導我到那個點的變量的行爲都如預期的那樣。

Cons_NaNs是一個數據幀,Cons_NaNs_count是一個整數,Cons_NaNs_str是一個字符串。

所以我退出ipython,重新啓動它並重新導入所有內容,現在它可以正常工作。但是不得不退出ipython。大多數情況下,這意味着必須重新導入數十件事並執行幾十個命令,才能真正測試我目前正在進行的工作。

+3

您是否試過['reload'](https://docs.python.org/2/library/functions.html#reload)? – jonrsharpe

回答

2

這不僅適用於ipython,而且Python通常在第一次導入sys.modules時緩存模塊。因此,在第一次導入之後,每當您嘗試導入時,都會從sys.modules獲得緩存模塊對象。

爲了讓Python重新加載模塊對象而不必重新啓動Python,以便對模塊所做的更改反映出來,您應該使用reload() built-in function (Python 2.x)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()

+0

如何在自制模塊中使用2.x中的'reload'? ''reload(mymodule)''''reload('mymodule.py')''和'reload(readCSVts)'全部失敗,返回值爲NameError:name'mymodule'未定義'或'TypeError:reload –

+0

做'import mymodule;重新加載(mymodule)'。 –

+0

此外,reload()需要模塊對象,而不是字符串。 –

0

當你殺死IPython的筆記本電腦服務器並重新啓動它,你將有一個新的內核實例不與您的筆記本電腦堅持本身。 您應該通過運行所有單元打開筆記本電腦後立即啓動工作流程。在頂部的菜單中選擇「細胞>運行所有」

+0

我只是在使用「普通」的ipython。這裏沒有筆記本。 –

4

有一個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 

該模塊沒有明確地重新加載它重新加載,和從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) 
+0

謝謝,這非常有幫助!但現在,如果需要,我更願意手動重新加載。 –

+1

@JC_CL,'dreload'可以做到這一點,'dreload(module)'不需要爲python2或3進行任何導入 –

相關問題