Python中的插件管理器
我对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
(我可以想象使用拓扑排序算法来处理插件之间的依赖关系,以决定插件初始化的顺序。)
我想实现多线程,也就是说每个插件都在自己的线程中运行,并且有一个工作队列,用来按顺序执行函数调用。当一个插件调用另一个插件的函数时,它会先调用管理器,管理器再把这个函数调用放入另一个插件的队列中。
此外,管理器还应该提供一种事件系统,插件可以在其中注册自己的事件,并成为其他插件事件的监听者。
我还希望能够在代码更改或线程崩溃的情况下重新加载插件,而不需要关闭管理器或应用程序。我已经阅读了如何卸载(重新加载)Python模块?相关内容。
再强调一下:管理器不应该提供其他功能,只需支持插件之间的通用通信接口,能够并行运行(以多线程方式,且插件不需要知道这一点),以及恢复更新或崩溃的插件。
所以我的问题是:在Python中实现这个功能可能吗?如果可以的话,这个粗略的设计有没有什么错误?我非常希望能得到一些好的建议。
其他“资料”: 在Python中实现插件系统
2 个回答
查看一下 yapsy
插件,链接在这里:https://github.com/tibonihoo/yapsy。这个应该对你有帮助。
首先,最基本的,你需要提供一个基础的插件类,这个类是你应用程序中所有插件的基础。
接下来,我们需要把所有插件导入进来。
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
这只是我想到的初步想法。显然,还需要更多的内容来完善这个思路,但这应该是一个很好的起点。