我想在我的代码中使用插件系统。我一直在寻找简单(但功能强大)的python模块,并找到了Yapsy(以及其他一些)。
这正是我所寻找的,但Yapsy发现插件的方式不是很灵活,需要一个插件信息文件。我想摆脱它,而不必分叉代码(如果我开始依赖Yapsy,我想确保我将从它获得所有更新,而不必每次都重新编译它。)
我推出了这个快速而肮脏的解决方案,它运行良好,但不会提高“发现”过程的灵活性:
#!/usr/bin/env python
import os
import logging
from cStringIO import StringIO
from yapsy.PluginManager import PluginManager
from yapsy.IPlugin import IPlugin
from yapsy.PluginInfo import PluginInfo
class MyPluginManager(PluginManager):
"""
My attempt to get rid of the plugin info file...
"""
def __init__(self,
categories_filter={"Default":IPlugin},
directories_list=None,
plugin_info_ext="plugin.py"):
"""
Initialize the mapping of the categories and set the list of
directories where plugins may be. This can also be set by
direct call the methods:
- ``setCategoriesFilter`` for ``categories_filter``
- ``setPluginPlaces`` for ``directories_list``
- ``setPluginInfoExtension`` for ``plugin_info_ext``
You may look at these function's documentation for the meaning
of each corresponding arguments.
"""
self.setPluginInfoClass(PluginInfo)
self.setCategoriesFilter(categories_filter)
self.setPluginPlaces(directories_list)
self.setPluginInfoExtension(plugin_info_ext)
def _gatherCorePluginInfo(self, directory, filename):
"""
Gather the core information (name, and module to be loaded)
about a plugin described by it's info file (found at
'directory/filename').
Return an instance of ``self.plugin_info_cls`` and the
config_parser used to gather the core data *in a tuple*, if the
required info could be localised, else return ``(None,None)``.
.. note:: This is supposed to be used internally by subclasses
and decorators.
"""
# now we can consider the file as a serious candidate
candidate_infofile = os.path.join(directory,filename)
print candidate_infofile
# My hack : just create a StringIO file with basic plugin info
_fname = filename.rstrip(".py")
_file = StringIO()
_file.write("""[Core]
Name = %s
Module = %s
""" % (_fname, _fname))
_file.seek(0)
# parse the information file to get info about the plugin
name,moduleName,config_parser = self._getPluginNameAndModuleFromStream(_file, candidate_infofile)
print name, moduleName, config_parser
if (name,moduleName,config_parser)==(None,None,None):
return (None,None)
# start collecting essential info
plugin_info = self._plugin_info_cls(name,os.path.join(directory,moduleName))
return (plugin_info,config_parser)
这个hack只是假设插件有一个扩展名“.plugin.py”(或“.plugin”用于目录,但我没有测试它)。然后我创建一个cSringIO文件来欺骗Yapsy并让它认为他找到了一个插件信息文件。 (通过设置适当的变量,仍然可以在插件中提供其他信息:author,description ...)。
我想知道是否有更好的方式,或者人们是否已经这样做了。这个hack显然太粗糙而不是非常有用,我希望有一些更灵活的东西:插件可以通过其插件信息文件(如原始代码中)或插件名称的模式(可能使用re
,允许使用前缀,后缀......)。据我所知,实施这些想法需要比我已经完成的更复杂的黑客...
答案 0 :(得分:0)
好的,我已经实现了Yapsy插件管理器的一个分支,并实际上与该软件包的作者保持联系。一旦文档和测试完成,我认为这可能会包含在Yapsy的下一个版本中。