2011-09-14 5 views
2

私はPythonには比較的新しい(小さなWebサーバーやローカルネットワークチャットのような1時間のスクリプトをすでに行っています)、プラグインマネージャーをプログラムしたいと思っています。 私の考えは、以下のような特徴を持っているプラ​​グインのインタフェースは、そこにあることを、次のとおりです。Pythonのプラグインマネージャー

getDependencies -> all dependencies of the plugin to other plugins 
getFunctions -> all functions that this plugin introduces 
initialize -> a function that is called when loading the plugin 

(私は、プラグインが初期化される順序を決定するために、依存関係にトポロジカル整列アルゴリズムを持つことが想像できます。 )

私はマルチスレッドを実装したいと思います。つまり、各プラグインは独自のスレッドで実行され、順次実行される関数呼び出しの作業キューがあります。プラグインが別のプラグインの機能を呼び出すと、プラグインはマネージャを呼び出します。マネージャは、他のプラグインのキューに関数呼び出しを挿入します。

さらに、マネージャは、プラグインが独自のイベントを登録して他のイベントのリスナーになるようなイベントシステムを提供する必要があります。

また、マネージャ/アプリケーションをシャットダウンすることなく、コードが変更された場合やスレッドがクラッシュした場合に、プラグインをリロードすることができます。私はすでにこれと一緒にHow do I unload (reload) a Python module?を読んでいます。

もう一度明確にする:マネージャは、相互に共通の通信インターフェイスを持つプラグインをサポートする以外の機能は提供しないでください(プラグインを必要とせずにマルチスレッドで実行する機能)。これを認識して)、更新された/クラッシュしたプラグインを復元します。

私の質問は次のとおりです:これはpythonでこれを行うことは可能ですか?そしてもしそうなら、この大まかなスケッチにデザインミスがありますか?私はこれに関する良いアドバイスを感謝します。

その他の「文学」:最も基本的なレベルで Implementing a Plugin System in Python

+0

具体的な詳細を教えてください。実際にやるべきプラグインは何ですか? Pythonのネイティブパッケージシステムにフックすることで、プラグインシステムを実装しました。それはスレッドや何かではなく、動作します。 :) –

+0

@bebrawWellこれまでは非常に普遍的な設計で、私はそれを後のプロジェクトで再利用するためにそのまま残しておきたいと思います。 – Nobody

+1

私はちょうどこれによって来た、http://stackoverflow.com/questions/932069/building-a-minimal-plugin-architecture-in-python。そこにはいくつかの出発点があります。 –

答えて

6

、すべての最初の、あなたのアプリケーションのために書かれたすべてのプラグインのためのベースとなる基本的なプラグインクラスを提供したいです。

次はすべてインポートする必要があります。 Pythonの2.7または3.1以上で

class PluginLoader(): 
    def __init__(self, path): 
     self.path = path 

    def __iter__(self): 
     for (dirpath, dirs, files) in os.walk(self.path): 
      if not dirpath in sys.path: 
       sys.path.insert(0, dirpath) 
     for file in files: 
       (name, ext) = os.path.splitext(file) 
       if ext == os.extsep + "py": 
        __import__(name, None, None, ['']) 
     for plugin in Plugin.__subclasses__(): 
      yield plugin 

、代わりの __import__(name, None, None, [''])、考慮してください。

import importlib # just once 
importlib.import_module(name) 

は、これはすべてのプラグインファイルをロードし、私たちのすべてのプラグインを提供します。次に、自分の見たようにプラグインを選択して使用します。

from multiprocessing import Process, Pipe 

plugins = {} 

for plugin in PluginLoader("plugins"): 
    ... #select plugin(s) 
    if selected: 
     plugins[plugin.__name__], child = Pipe() 
     p = Process(target=plugin, args=(child,)) 
     p.start() 

... 

for plugin in plugins.values(): 
    plugin.put("EventHappened") 

... 

for plugin in plugins.values(): 
    event = plugin.get(False) 
    if event: 
     ... #handle event 

これはまさに最初のことです。明らかに肉のためにはるかに多くのものが必要になるでしょうが、それは働くための良い基礎でなければなりません。