我有以下文件结构,它使用Yapsy实现了一个非常简单的插件架构。
from yapsy.IPlugin import IPlugin
class BasePlugin(IPlugin):
def process(self):
# Do some stuff common to all plugins
pass
from Plugins.BasePlugin import BasePlugin
class TestPlugin(BasePlugin):
def process(self, info):
super(TestPlugin, self).process()
# Do stuff
return "done"
from yapsy.PluginManager import PluginManager
from Plugins.BasePlugin import BasePlugin
import logging
logging.basicConfig(level=logging.DEBUG)
# See note 1
manager = PluginManager() # Does not work
manager = PluginManager(categories_filter={'BasePlugin': BasePlugin}) # Works
def init_plugins():
# Load the plugins from the plugin directory.
manager.setPluginPlaces(["Plugins"])
manager.collectPlugins()
# Loop round the plugins and print their names.
for plugin in manager.getAllPlugins():
manager.activatePluginByName(plugin.name, "BasePlugin")
print "Plugin path: {}".format(plugin.path)
print "Plugin obj: {}".format(plugin.plugin_object)
result = plugin.plugin_object.process(info)
TestPlugin还有正确的.yapsy-plugin信息文件。
没有过滤器(注1)Yapsy尝试实例化BasePlugin而不是我的TestPlugin,尽管插件的名称是“TestPlugin”。例如:
Plugin path: /home/user/python/Plugins/TestPlugin
Plugin obj: <Plugins.BasePlugin.BasePlugin object at 0x7f159af22050>
如果我包含过滤器,那么插件会正确加载,我的TestPlugin类会被实例化并改为使用。
DEBUG:yapsy:Activating plugin: BasePlugin.test
Plugin path: /home/david/python/Plugins/TestPlugin
Plugin obj: <yapsy_loaded_plugin_test_0.TestPlugin object at 0x7f4dad7d4050>
我是否在继承上做错了,或者这就是Yapsy的工作方式?我不明白为什么它会尝试使用BasePlugin而不是TestPlugin,尽管找到了正确的文件。
我是否需要实现类别以扩展IPlugin并提供我自己的基类?
答案 0 :(得分:3)
您遇到了一个已知的yapsy问题,该问题与检测文件中的插件并对其进行分类的方式有关。
在https://yapsy.readthedocs.org/en/latest/Advices.html#plugin-class-detection-caveat的yapsy的文档的问题排查部分对此进行了解释。
由于这些已经是我自己的话,我只是将它们复制粘贴在这里,但如果有些事情不清楚,请随意询问精确度。
每个模块必须只定义一个插件。这意味着您不能拥有两个指向同一模块的插件描述文件。
由于“继承分类”系统,您不能直接在主插件文件中导入IPlugin
的子类,而是导入其包含模块并使您的插件类继承自ContainingModule.SpecificPluginClass
如下例所示。
以下代码不起作用(类MyBasePluginClass
将被检测为插件的实现,而不是MyPlugin
):
from myapp.plugintypes import MyBasePluginClass
class MyPlugin(MyBasePluginClass):
pass
相反,您应该执行以下操作:
import myapp.plugintypes as plugintypes
class MyPlugin(plugintypes.MyBasePluginClass):
pass