私のコードの中でプラグインシステムを使いたいです。私は単純な(しかし強力な)Pythonモジュールを見回し、Yapsyを見つけました。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)
このハックは、単にプラグインが「拡張子を持っていることを前提としています。 plugin.py "(ディレクトリの場合は" .plugin "だが、テストしなかった)。次に、私はYapsyを欺くためにcSringIOファイルを作成し、彼がプラグイン情報ファイルを見つけたと思うようにします。 (プラグインには、作成者、説明などの適切な変数を設定することによって、追加情報を引き続き提供することができます)。
もっと良い方法があるのか、それとも人々がすでにそれをしているのだろうかと思います。このハックは非常に面倒で、本当に便利ではありません。プラグインは、プラグイン情報ファイル(元のコードのように)またはプラグイン名のパターン(おそらくre
、接頭辞、接尾辞の使用を許可します...)。私の知る限り見るように、これらのアイデアを実現したことは、私はすでにやったものよりもはるかに複雑なハックを必要とする...
の代わりにあなたが収集した情報をもとに、独自の 'PluginInfo'オブジェクトを生成しない理由を解析する必要が偽のファイル、などの情報を梱包?他に何もなければ、それはあまりハッキーではありません。また、あなたの '__init__'から' PluginManager .__ init __() 'を呼び出すべきでしょう。 – alexis
@alexisあなたの提案をありがとう。しかし、PluginInfoを生成するには、はるかに複雑なハックが必要です(複数のクラス/メソッドを変更する必要があります)。 'PluginManager .__ init __()'については正しいですが、元のメソッドのすべての内容をコピーしたので、これは必須ではありません(汚い/素早いハックです:))。 – mhavel