Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

IPython:`autoreload 2`の動作確認

More than 1 year has passed since last update.

環境

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

yuji38kwmt
愛知のIT企業で修行しております。2018年4月に転職しました。 基本的に自分用のメモとして、記事を書いております。 所属先の見解とは一切関係ありません。 https://qiita.com/yuji38kwmt/items/a474ad97e0d86f6081a2
kurusugawa
「いいソフトウェアを楽に作る」技術を追求する企業。今は、機械学習、画像認識中心。
http://kurusugawa.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away