2

次のディレクトリ構造があります

+ code
|
--+ plugins
  |
  -- __init__.py
  -- test_plugin.py (has a class TestPlugin)
  -- another_test_plugin.py (has a class AnotherTestPlugin)
--+ load.py
--+ __init__.py

load.py では、ユーザーが指定したクラスのみを初期化できるようにしたいと考えています。たとえば、私が次のようなことをするとしましょう

$ python load.py -c test_plugin # Should only import test_plugin.py and initialize an object of the TestPlugin class

「imp」モジュールを使用してそれを行うのに問題があります。「そのようなファイルまたはディレクトリはありません」と言い続けます。私の理解では、どういうわけかパスを正しく理解していないということです。誰かがこれで私を助けることができますか?

4

3 に答える 3

0

わかりました、あなたの問題はパスに関連する問題です。スクリプトが load.py と同じディレクトリで実行されることを期待していますが、そうではありません。

あなたがしなければならないことは次のようなものです:

import imp, os, plugins

path = os.path.dirname(plugins.__file__)
imp.load_source('TestPlugin', os.path.join(path, 'test_plugin.py')

ここで、 plugins はすべてのプラグインを含むモジュール (つまり、空の のみ__init__.py) であり、プラグイン モジュールのファイルへのフル パスを取得するのに役立ちます。

于 2013-05-08T10:50:38.273 に答える
0

「プラグイン」検出ツールが必要な場合の別の解決策:

import imp, os
import glob

def load_plugins(path):
  """
  Assuming `path` is the only directory in which you store your plugins,
  and assuming each name follows the syntax:
  plugin_file.py -> PluginFile
  Please note that we don't import files starting with an underscore.

  """
  plugins = {}
  plugin_files = glob.glob(path + os.sep + r'[!_]*.py')
  for plugin_path in plugin_files:
    module_name, ext = os.path.splitext(plugin_path)
    module_name = os.path.basename(module_name)
    class_name = module_name.title().replace('_', '')
    loaded_module = imp.load_source(class_name, plugin_path) # we import the plugin
    plugins[module_name] = getattr(loaded_module, class_name)
  return plugins

plugins = load_plugins(your_path_here)
plugin_name = sys.argv[3]
plugin = plugins.get(plugin_name)
if not plugin:
    # manage a not existing plugin
else:
    plugin_instance = plugin() # creates an instance of your plugin

このように、キーを変更して別の名前を指定することもできます (例: 'test_plugins' => 'tp')。プラグインを初期化する必要はありませんが、実行時にプラグインをロードしたいときはいつでもこの関数を実行できます。

于 2013-05-08T10:57:59.120 に答える
-7
exec('import ' + sys.argv[2])
obj = test_plugin.TestPlugin()

ここで sys.argv[2] は、コマンド ライン引数からの「test_plugin」文字列です。

編集: exec の使用を避ける別の方法:

import importlib
mod = importlib.import_module(sys.argv[2])
于 2013-05-08T10:13:07.543 に答える