0. はじめに
0.1 動機
簡潔で情報漏れのない日本語のまとめ記事がなく,意外と実行までたどり着くのに難儀したのでまとめを書くことにしました1.とくに from X import Y の型が厄介です.
基本的には自作パッケージ(モジュール)のリロードを行うことが目的です.自作でも from X import * が便利だったので,急務だったというわけです.
0.2 概要
- import したモジュールや関数を unimport する
- from X import Y で import したモジュールを reload する(当然 import X や from X import * も可)
0.3 実行環境
Python 3.8.6
jupyter-notebook : 6.1.4
#1. モジュールのアンインポート
1.1 パッケージ・モジュール
パッケージやモジュールを以下のようにインポートしたとします
import module as importname
以下でこのモジュールをアンインポートできます.
del importname
1.2 関数・変数
関数や変数も以下で消去できます.
from module import f
del f
あまりないとは思いますが,from module import *
した場合は変数名を namespace で探します.
from module import *
if 'f' in dir():
del f
2. モジュールのリロード
2.1 import X 型
importlib パッケージの reload 関数を使ってください.
# import X
from importlib import reload # >= python 3.4
reload( X )
2.2 from X import Y 型
自作パッケージを作る時に役に立ちます.Jupyter notebook のファイルのセーブだけでは関数などの書き換えが行われないからです.
もちろん一度 ipynb 上に変更箇所をコピーしても良いと思います.ただ,リロードからも関数の中身の再度読み込みできるようにしておくと便利です.
# from X import Y
from importlib import reload # >= python 3.4
import X
reload( X )
from X import Y # from X import *
モジュールの内容を微修正するたびにカーネルや Jupyter notebook を再起動するのは面倒くさいです.
VSCodeでも,Pythonを書く場合事情は同じです.
しかし,reload できれば shift (command, VSCodeならctrl) + enter を押すだけなので簡単です.
3. 具体例
del
については scipy や sympy で例を考えます.
reload
については foo()
が2パターンあるテストモジュールを考えます.
今は使いませんが,グローバル変数の例としてわざと x も定義しています.
2つ目のfoo()
はここではコメントアウトしてあります.
x = 0
print(x)
# 1
def foo(): print('bar')
# 2
#def foo(): print('bar1')
if __name__ == '__main__':
print('This is a test module named testmod.')
print('x = '+str(x))
詳細についてはこのページを御覧ください(github).
まとめ
アンインポートについてはdel
,リロードについてはimportlib.reload
で可能です.
from import
した場合のリロードについては工夫が必要です.
-
英語や和訳サイトなら基本的なことはいくらでもありますが,from X import * となるとこれはもう絶望的です.「推奨されていない」なんてよく聞きますが,
from scipy.constants import *
とか便利,というより不可避なんですよね.SymPy の公式などでもソースコードでよく見かけます.
Matrices — SymPy 1.7.1 documentation ← from sympy import * の使用例
Zeta functions, L-series and polylogarithms — SymPy 0.7.4.1 documentation ← from mpmath import * ↩