環境
- Python 3.6.0
- IPython 6.4.0
背景
pythonコードの動作確認を、IPythonで行っています。
自動的にpythonファイルをリロードするよう、以下のコマンドを設定しています。
In [1]: %load_ext autoreload
In [2]: %autoreload 2
期待した通りに自動リロードされないときがあったので、動作確認してその結果をまとめました。
%autoreload 2
の動き
Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.
http://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html?highlight=reload 引用
動作確認
pythonコード
以下のpythonファイルを使います。
# 変更前
class Sample:
def instance_method1(self):
print("instance_method")
def func1():
print("func1")
# 変更後
class Sample:
def instance_method1(self):
print("instance_method1 changed")
def instance_method2(self):
print("instance_method2 added")
def func1():
print("func1 changed")
def func2():
print("func2 added")
IPythonで動作確認
ファイル変更前の状態で、コマンド実行
In [1]: %load_ext autoreload
In [2]: %autoreload 2
In [3]: from sample import *
In [4]: func1()
func1
In [5]: s = Sample()
In [6]: s.instance_method1()
instance_method1
ファイルを変更した後、コマンド実行
In [7]: func1()
func1 changed
In [8]: s.instance_method1()
instance_method1 changed
In [9]: func2()
NameError: name 'func2' is not defined
In [10]: s.instance_method2()
AttributeError: 'Sample' object has no attribute 'instance_method2'
メソッド内の変更は反映されましたが、メソッドの追加は反映されませんでした。
from sample import *
でリロード
In [13]: from sample import *
In [14]: func2()
func2 added
In [15]: s.instance_method2()
AttributeError: 'Sample' object has no attribute 'instance_method2'
In [16]: s = Sample()
In [17]: s.instance_method2()
instance_method2 added
import
すると、グローバルな関数の追加は反映されましたが、インスタンスメソッドの追加は反映されませんでした。
再度、Sample
クラスのインスタンスを生成する必要がありました。
まとめ
autoreload 2
を設定すると、以下の動きになることが分かりました。
- メソッドの変更は反映される
- メソッドの追加は反映されない。再度
import
が必要。 - インスタンスメソッドの追加を反映させるには、
import
に加えて再度インスタンスを生成する必要がある
autoreload
の注意事項
自動リロードは、予期しない動きになるそうです。
Reloading Python modules in a reliable way is in general difficult, and unexpected things may occur.
メソッドの削除も反映されないとのこと。
Functions that are removed (eg. via monkey-patching) from a module before it is reloaded are not upgraded.