シナリオは次のとおりです。
外部スクリプトをプラグインとして使用するフレームワークを構築しています。人々は、何らかのインターフェースに準拠するスクリプトへの「アダプター」を作成できるようになります。これらのアダプターは、フレームワークに統合されて (したがって、プラグインの登録が必要です)、または単純なインポートによって「大まかに」使用されます。
つまり、アダプターはスクリプトの使用法を標準化するためのものです。
複雑すぎると考えているかもしれませんが、現在取り組んでいる解決策は、インターフェイス (およびいくつかのユーティリティ メソッド) を定義する抽象クラスを作成することです。抽象クラスのモジュールは 1 回だけロードされ、フレームワークは自己登録メタクラスを含むバージョンをロードしますが、プラグイン自体はより単純なバージョンをロードします (抽象クラスを最初に登録したものが優先されます)。
これにより、プラグインは、抽象クラスを定義するファイル、したがって「契約」を持つようになります。問題はありません。
実際には 2 つの異なる抽象クラスを使用するつもりはありませんが、ロードされる場所 (フレームワークまたはプラグイン自体) に応じて動作が異なるモジュール ファイル内の 1 つの抽象クラスを使用するつもりはありません。しかし、それは関係ないはずです(私は思います)。
これは、抽象クラス/メタクラスがどのように見えるかです
#imp/plugin.py
import abc
class PluginAbstract(object):
class __metaclass__(abc.ABCMeta):
def __init__(self, name, bases, namespace):
if name != 'PluginAbstract':
pass #We can register the new "sub-class" if required
return abc.ABCMeta.__init__(abc.ABCMeta, name, bases, namespace)
そして、実装は次のようになります。
#impl/MyPlugin.py
if 'plugin' not in locals():
from impl import plugin
class MyPlugin(plugin.PluginAbstract):
pass #rest of the implementation....
したがって、フレームワークが既に登録されPluginAbstract
ている場合は継承され、そうでない場合はコントラクト ファイル impl/plugin.py
のものが使用されます。
アダプターにフレームワークのインストールを要求したくないため、インターフェースを備えた単一のファイルです。
この戦略は理にかなっていますか?他のオプションはありますか?