在 Jupyter 中如何從新導入特定的 Python 文件?

Jupyter 是數據分析領域很是有名的開發環境,使用 Jupyter 寫數據分析相關的代碼會大大節約開發時間。python

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

若是直接寫 Python 文件來調用數據分析模塊,那麼使用方法很是簡單:spa

from analyze import FathersAnalyzer

data = [...]
father = FathersAnalyzer(data)
result = father.analyze()
print(f'分析結果爲:{result}')
複製代碼

如今,你須要使用 Jupyter 來調用這個分析模塊。你應該怎麼在 Jupyter裏面調用?code

你可能會以爲,這還不簡單嗎?直接把這個模塊的代碼與 Jupyter Notebook 的 .ipynb 文件放在一塊兒,而後在 Jupyter 裏面像導入普通模塊那樣導入便可,以下圖所示:cdn

那麼如今問題來了,若是我此時修改了 analyze.py文件,會出現什麼狀況呢?blog

咱們改一下看看,以下圖所示。ip

從新運行這個 Cell 中的代碼,代碼中雖然有from analyze import FathersAnalyzer,看起來像是從新導入了這個模塊,可是運行卻發現,它運行的是修改以前的代碼。開發

這是由於,一個 Jupyter Notebook 中的全部代碼,都是在同一個運行時中運行的代碼,當你屢次導入同一個模塊時,Python 的包管理機制會自動忽略後面的導入,始終只使用第一次導入的結果(因此使用這種方式也能夠實現單例模式)。數據分析

那麼若是我在修改了被導入的包之後,想從新導入它怎麼辦呢?有3種方案:string

  • 重啓整個 Notebook。但這樣會致使當前運行時裏面的全部變量所有丟失。
  • 使用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導入的模塊。這樣作的代價是,運行會慢一些。

相關文章
相關標籤/搜索