このサイトについて

PythonでPluginアーキテクチャ

PythonでPluginアーキテクチャ

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)を呼び出す
2010-08-27 04:40