Pythonのモジュールを動的に読み込んでプラグインとして利用するための簡易な方法。
たとえば,以下のような構成のフォルダがあるとして,mod.pyとpack/__init__.pyにはそれぞれfoo()という関数が書かれているとする。
[plugins]--+
|
+- mod.py
|
+- [pack] --+
|
+- __init__.py
pluginsディレクトリと同じ位置に以下のスクリプトを置くと,pluginsディレクトリ以下にあるPythonのモジュールやパッケージを動的に読み込み,モジュールオブジェクトとしてリストに格納,モジュールのfoo()という関数を呼び出す。似たような方法を使うと,RSSやAtomのフィーダープラグインなんかも作れるね。
クラスをプラグインにするなら,register_class()みたいな関数を用意しておき,クラス名とクラスオブジェクトを返すようにするのかな(Zopeみたいに)。
# coding=utf-8
import imp
import os
def load_module(module_name,basepath):
""" モジュールをロードして返す
"""
f,n,d = imp.find_module(module_name,[basepath])
return imp.load_module(module_name,f,n,d)
def load_plugins(basepath):
""" Pluginをロードしてリストにして返す
"""
plugin_list = []
for fdn in os.listdir(basepath):
try:
if fdn.endswith(".py"):
m = load_module(fdn.replace(".py",""),basepath)
plugin_list.append(m)
elif os.path.isdir(fdn):
m = load_module(fdn)
plugin_list.append(m)
except ImportError:
pass
return plugin_list
if __name__ == "__main__":
plugindir = "plugins" # Pluginが入っているディレクトリ
cwd = os.getcwd()
moduledir = os.path.join(cwd,plugindir)
plugins = load_plugins(moduledir) # Pluginを読み込む
for p in plugins:
p.foo() # 読み込んだPluginの関数(foo)を呼び出す