LoginSignup
5
3

More than 5 years have passed since last update.

IPython:`autoreload 2`の動作確認

Posted at

環境

  • Python 3.6.0
  • IPython 6.4.0

背景

pythonコードの動作確認を、IPythonで行っています。
自動的にpythonファイルをリロードするよう、以下のコマンドを設定しています。

IPython_console
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ファイルを使います。

sample.py
# 変更前
class Sample:
    def instance_method1(self):
        print("instance_method")

def func1():
    print("func1")

sample.py
# 変更後
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 *でリロード

IPython_Console
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.

https://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html?highlight=autoreload#caveats 引用

メソッドの削除も反映されないとのこと。

Functions that are removed (eg. via monkey-patching) from a module before it is reloaded are not upgraded.

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3