はてブロ@ama_ch

https://twitter.com/ama_ch

モジュールの一括リロード

「初めてのPython」p.353より

#!usr/bin/env python
# -*- coding: utf-8 -*-
""" reloadall.py
引数として指定したモジュール自身と、そのモジュール内で
インポートしているすべてのモジュールをリロードする
"""
import types

def status(module):
    print "reloading", module.__name__

def transitive_reload(module, visited):
    if not visited.has_key(module):  # リロード済みでないか確認
        status(module)  # 指定のモジュールをリロードし、
        reload(module)  # さらにリロード対象を探す
        visited[module] = None
        for attrobj in module.__dict__.values():     # すべての属性にアクセス
            if type(attrobj) == types.ModuleType:    # 属性がモジュールなら
                transitive_reload(attrobj, visited)  # 自分自身を呼び出す
    visited = {}
    for arg in args:
        if type(arg) == types.ModuleType:
            transitive_reload(arg, visited)

if __name__ == "__main__":
    import reloadall
    reload_all(reloadall)

実行結果

$ python reloadall.py
reloading reloadall
reloading types
>>> import reloadall
>>> import twitter
>>> reloadall.reload_all(twitter)
reloading twitter
reloading tempfile
reloading fcntl
--- 中略 ---
reloading bisect
reloading urlparse
reloading md5


あるモジュールa, b, cがあり、aの中でb, cをインポートしているとします。
a, b, cに変更を加え、aをリロードしても、aの中でインポートしているb, cはリロードされません。
そんな時に、上記のreloadallというモジュールを利用することで、一括リロードできます。
このようにリロードの動作は割と複雑なので、モジュールのリロードは極力避けるべきですね。