2012-03-18 3 views
2

私は開発中のPythonアプリケーションで、実行時に提供される情報(設定ファイルなど)に基づいてパッケージ(プラグイン)を動的にロードしたいと考えています。sys.pathを調整する必要のある名前空間のパッケージをインポートするには?

私はロードするプラグインにパスを追加するためにsys.pathを変更しますが、これは一般的にはうまくいきますが、プラグインがすでに初期化されている名前空間内の名前空間パッケージです(問題はとにかく)。

例:

# lib1 contains plugins/__init__.py and plugins/foo/__init__.py 
# lib2 contains plugins/__init__.py and plugins/bar/__init__.py 
# plugins is a namespace package 

import sys 

sys.path.append ('lib1') 
import plugins.foo 

sys.path.append ('lib2') 
import plugins.bar 

上記のコードははImportErrorで失敗し、「インポートplugins.foo」ラインは、プラグインの名前空間/パッケージを初期化し、それ以上の試みは他のためのsys.pathを検索するために行われていないと思われるので、名前空間内のパッケージ

私はこれまでのコードに変更した場合:

sys.path.append ('lib1') 
sys.path.append ('lib2') 
import plugins.foo 
import plugins.bar 

を両方とも輸入は動作しますが、私はplugins.fooのインポート後のsys.pathに追加したいと思います。

だから、私の質問は以下のとおりです。

  1. 私の仮定は、第二の輸入が原因 名前空間のパッケージの失敗したことを正しいですか?
  2. 回避策はありますか?
+0

あなたは本当にsys.pathを全く混乱させる必要はありません。ただパッケージを使用してください。動的インポートの場合、 '__import__'関数を呼び出すことができます。あるいは 'imp'モジュールを使います。 – Keith

+0

私が正しく従っているのであれば、パッケージに '' plugins''をパッケージ化せずに '' plugins/lib1''と '' plugins/lib2''をパスに追加してから '' import foo''と 'インポートバー '? –

+0

しかし、私はあなたの本当の疑問は、Pythonでプラグインシステムを作る方法だと思う - これを見て:http://stackoverflow.com/questions/7417997/plugin-manager-in-python/7418304#7418304 –

答えて

1

あなたの診断は正しいと思います。 plugins.fooをインポートすると、pythonもpluginsをロードし、sys.modulesにキャッシュします。私はあなたの設定を複製していませんが、barをインポートする前にdel sys.modules['plugins']を試してみました。問題が解決しない場合は、pluginsをリロードしてみてください。

sys.path.append ('lib2') 
import plugins 
reload(plugins) 
import plugins.bar 

は、私は一般的な合意ではなく、プログラムの実行中には良い考えで、そのリロードが認めなければなりません。 「適切な」ソリューションは、パッケージからインポートを開始する前にフルsys.pathを設定できるワークフローを把握することです。あるいは、1つのパッケージを別の場所に広げないこともできます。

+0

私はなかったリロードに精通し、私の問題を解決します。ありがとう! – warp

関連する問題