1. 程式人生 > 程式設計 >在 Jupyter 中重新匯入特定的 Python 檔案(場景分析)

在 Jupyter 中重新匯入特定的 Python 檔案(場景分析)

Jupyter 是資料分析領域非常有名的開發環境,使用 Jupyter 寫資料分析相關的程式碼會大大節約開發時間。

設想這樣一個場景:別的部門的同事傳給你一個數據分析的模組,用於實現對資料的高階分析。模組裡面有上百個函式。

如果直接寫 Python 檔案來呼叫資料分析模組,那麼使用方法非常簡單:

from analyze import FathersAnalyzer

data = [...]
father = FathersAnalyzer(data)
result = father.analyze()
print(f'分析結果為:{result}')

現在,你需要使用 Jupyter 來呼叫這個分析模組。你應該怎麼在 Jupyter裡面呼叫?

你可能會覺得,這還不簡單嗎?直接把這個模組的程式碼與 Jupyter Notebook 的 .ipynb 檔案放在一起,然後在 Jupyter 裡面像匯入普通模組那樣匯入即可,如下圖所示:

那麼現在問題來了,如果我此時修改了 analyze.py 檔案,會出現什麼情況呢?

我們改一下看看,如下圖所示。

重新執行這個 Cell 中的程式碼,程式碼中雖然有 from analyze import FathersAnalyzer ,看起來像是重新匯入了這個模組,但是執行卻發現,它執行的是修改之前的程式碼。

這是因為,一個 Jupyter Notebook 中的所有程式碼,都是在同一個執行時中執行的程式碼,當你多次匯入同一個模組時,Python 的包管理機制會自動忽略後面的匯入,始終只使用第一次匯入的結果(所以使用這種方式也可以實現單例模式)。

那麼如果我在修改了被匯入的包以後,想重新匯入它怎麼辦呢?有3種方案:

importlib

但這種方案弊端也很明顯——除非你按順序執行每一個 Cell,否則,你的程式碼會變成下圖這樣:

在每一個 Cell 裡面都需要 重新載入一次分析模組,否則,很有可能在你單獨執行某一個 Cell 的時候,用的是老的程式碼,就會導致難以察覺的 bug。

使用 Jupyter 自帶的 %autoreload :

%load_ext autoreload
%autoreload 1
%aimport analyze 

data = 123
importlib.reload(analyze)
father = analyze.FathersAnalyzer(data)
result = father.analyze()
print(result)

執行效果如下圖所示:

其中關鍵的程式碼有三行:

%load_ext autoreload
%autoreload 1
%aimport analyze 

這三行程式碼只有在 Jupyter 裡面才能正常執行,在 普通的.py 檔案裡面這樣寫會報錯。它們的作用是:第1行啟動 autoreload 機制。第2行,設定自動載入通過 %aimport 匯入的模組。第3行使用 %aimport 匯入 analyze 模組。

這樣寫以後,任意一個 Cell 執行,所有被 %aimport 匯入的模組都會被重新載入一次。從而讓你每次都使用最新的程式碼。

當然,你還可以進一步偷懶,把特殊程式碼縮減為2行:

%load_ext autoreload
%autoreload 2

%autoreload 後面的引數被設定為2時,每次執行任意一個 Cell,都會自動重新載入所有 import xxx 匯入的模組。這樣做的代價是,執行會慢一些。

總結

以上所述是小編給大家介紹的在 Jupyter 中重新匯入特定的 Python 檔案的方法,希望對大家有所幫助!