2011-09-14 34 views
2

我對python比較新(已經做了一些像小型web服務器或本地網絡聊天的1h腳本),並且想要在其中編寫一個插件管理器。 我的想法是,有對插件的接口,它具有以下特點: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

@bebraw到現在爲止,這是一個非常通用的設計,我想我想讓它在以後的項目中重用它,所以現在沒有真正的細節,如果這對你來說可以。 – Nobody

+1

我剛來這個,http://stackoverflow.com/questions/932069/building-a-minimal-plugin-architecture-in-python。你可能會在那裏找到一些起點。 –

回答

6

在最基本的層面上,首先,你要提供一個基本的插件類,這是爲您的應用程序編寫的所有插件的基礎。

接下來我們需要將它們全部導入。

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 

在Python 2.7或3.1以上版本,而不是__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 

這正是來自於第一個在腦海中。顯然,肉食需要更多的東西,但它應該是一個很好的工作基礎。