Pythonでモジュールをアンインポートする方法
モジュールをインポートするときの問題点
Pythonで同名の別ファイルをインポートしようとすると、あとにインポートしたファイルがきちんとインポートされません。
なぜなら、 Python側がすでにインポートしているファイルだと勘違いしてしまうからです。
この問題を解決するために、先にインポートしているモジュールをアンインポートして、別の場所にある同名ファイルをインポートできるようにしましょう。
問題の検証
ここからは、問題の検証をしようと思うので、結論を急ぐ方は「アンインポートの解決策」を見てください。
まず例えば、以下のような2種類のスクリプトを用意しましょう。
以下のスクリプトは「Test.py」というタイトルのファイル。
このファイルは「A」というフォルダと、「B」というフォルダの2つに入れておきましょう。
ちなみに、Python 3.x系を使っているので、2.x系を使っている人は、print文の括弧を外すと動くはずです。
#!/usr/bin/env python # -*- coding: utf-8 -*- def print_path(): print(__file__)
以下のスクリプトは「Load.py」という名前のファイル。
「./A/Test.py」を読み込んで、print_path関数を実行し、「./B /Test.py」を読み込んで、print_path関数を実行します。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys sys.path.append('./A') import Test Test.print_path() sys.path.remove('./A') sys.path.append('./B') import Test Test.print_path() sys.path.remove('./B')
「sys.path」にモジュールのあるディレクトリを加えたあとに、「import」することで必要なファイルを使うことができます。
このファイルを実行すると、以下のように出力されます。
./A/Test.py ./A/Test.py
両方とも「./A/Test.py」であることから、「./B/Test.py」が呼ばれていないことがわかります。
このような状況ですと、いったん「./A/Test.py」をアンインポートしたほうが良さそうですね。
しかしながら、Pythonにはモジュールをインポートする「import」はあっても、アンインポートする「unimport」は見当たらないようです。
アンインポートの解決策
自分もちょっと悩んだのですが、実はモジュール情報を記憶している箇所を少し触ることで、モジュールのアンインポート機能が実装できるようです。
以下のスクリプトがアンインポート機能の実装です。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys sys.path.append('./A') import Test Test.print_path() sys.modules.pop('Test') # Unimport module forcely sys.path.remove('./A') sys.path.append('./B') import Test Test.print_path() sys.modules.pop('Test') # Unimport module forcely sys.path.remove('./B')
インポートしたモジュールは「sys.modules」に格納されているため、そこから該当の要素を取り除くことで、アンインポートできるようです。
これを実行すると、以下のような結果になります。
./A/Test.py ./B/Test.py
無事にアンインポートできているようです。
ちょっと強引な処理ですが、必要なときはこれで乗り切りましょう。