5

私は、主な設計指針の原則が拡張性であるプロジェクトに取り組んでいます。

クラス メソッドを使用して、読み込まれるプラグインのクラス名を登録するメタクラスを定義することにより、プラグイン システムを実装しました(各タイプのプラグインは、コア コードで定義された特定のクラスから継承します。アプリケーション)。基本的にこれは、開発者が自分のクラスを次のように定義する必要があることを意味します。

class PieChart(ChartPluginAncestor):
    # Duck typing:
    # Implement compulsory methods for Plugins 
    # extending Chart functionality

PieChartで利用可能な登録済みプラグインのリストに含まれるため、メインプログラムは彼の存在を認識しChartPluginAncestor.pluginsます。

マウント メソッドがクラス メソッドであるため、すべてのプラグインは、クラス コードがメモリに読み込まれるときに登録されます (したがって、そのクラスのオブジェクトがインスタンス化される前であっても)

システムは私にとっては十分に機能します ™ (ただし、アーキテクチャを改善する方法についての提案はいつでも受け付けています!) しかし、プラグイン ファイルを管理する最善の方法は何か (つまり、プラグインを含むファイルの場所と方法) を考えています。保管する必要があります)。

これまでのところ、開発目的で「プラグイン」と呼ばれるパッケージを使用しています。プラグイン クラスを含むすべての *.py ファイルをパッケージ ディレクトリにimport plugins置き、すべてのプラグインが適切にマウントされるように、main.py ファイルで発行するだけです。

編集:ジェフは、パッケージのさまざまなモジュールに含まれるクラスがすぐに利用できないことをコメントで指摘しましたimport plugins(デバッグ目的で、各クラスを個別にインポートしていたため、これに気づきませんでしたfrom plugins.myAI import AI)。

ただし、このシステムは、次のように、コードを開発およびテストしている間のみ有効です。

  • プラグインには独自のユニットテストが付属している場合があり、それらをメモリにロードしたくありません。
  • すべてのプラグインは現在メモリにロードされていますが、実際には同じ機能の代替バージョンである特定のプラグインが存在するため、2 つを切り替えることができることを知っておく必要がありますが、選択したものだけをメモリにロードしたい構成ペインから。
  • ある時点で、プラグインをインストールするための 2 つの場所が必要になります。システム全体の場所 (たとえば の下のどこか/usr/local/bin/) とユーザー固有の場所 (たとえば の下のどこか/home/<user>/.myprogram/) です。

だから私の質問は本当に - おそらく - 3つです:

  1. プラグイン コンテナー:私の目標にとって最も賢明な選択は何ですか? 単一のファイル?パッケージ?.py ファイルの単純なディレクトリ?)
  2. 必ずしもプラグインをロード (インポート) せずにプラグインの存在を認識する: Python イントロスペクションを使用してそうするスマートな方法は何ですか?
  3. プラグインを2つの異なる場所に配置する:それを行うための標準的な方法/ベストプラクティス(少なくともgnu/linuxの下)はありますか?
4

2 に答える 2

3

ニーズは複雑であるため、この質問に対処するのは困難です。とにかく私はいくつかの提案を試してみます。

プラグインを2つの異なる場所に配置する:それを行うための標準的な方法/ベストプラクティス(少なくともgnu / linuxの下で)はありますか?

良いアプローチはvirtualenvです。Virtualenvは、「分離された」Pythonインストールを構築するためのPythonモジュールです。これは、別々のプロジェクトを連携させるためのより良い方法です。プラグインと関連するプロジェクトモジュールを配置できる、まったく新しいサイトパッケージを入手できます。

試してみてください:http://pypi.python.org/pypi/virtualenv

プラグインコンテナ:私の目標にとって最も賢明な選択は何ですか?単一のファイル?パッケージ?.pyファイルの単純なディレクトリ?)

良いアプローチは、インポート時に「自己登録」を実行できるPythonパッケージです。パッケージディレクトリ内で適切なinit.pyを定義するだけです

例としては、http://www.qgis.org/wiki/Writing_Python_Plugins や、ここで説明されているAPIがありますhttp://twistedmatrix.com/documents/current/core/howto/plugin.html

http://pypi.python.org/pypi/giblets/0.2.1も参照してください

Gibletsは、Tracのコンポーネントアーキテクチャに基づくシンプルなプラグインシステムです。一言で言えば、gibletsを使用すると、インターフェイスを宣言し、結合せずにそれらを実装するコンポーネントを検出できます。

Gibletsには、ファイルパスまたはエントリポイントに基づくプラグイン検出と、アプリケーションで有効または無効になっているコンポーネントを管理するための柔軟な手段も含まれています。

于 2010-07-29T12:35:30.033 に答える
1

3 種類のプラグインを備えたプラグイン システムもありますが、うまくできたとは言えません。ここで詳細を確認できます。

内部プラグインの場合、パッケージ (例: MethodPlugins) があり、このパッケージには各プラグインのモジュール (例: MethodPlugins.IRV) があります。プラグインをロードする方法は次のとおりです。

  1. パッケージを読み込む ( import MethodPlugins)

  2. pkgutil.iter_modulesそこにすべてのモジュールをロードするために使用します (例: MethodPlugins.IRV)

  3. すべてのプラグインは共通の基本クラスから派生している__subclassess__ため、それらをすべて識別するために使用できます。

これにより、プラグインを実際にロードしなくても認識できるようになると思いますが、すべてをロードするだけなので、そうしません。

外部プラグインの場合、ユーザーがそれらを置くことができる特定のディレクトリがあり、それらos.listdirをインポートするために使用します。ユーザーは適切な基本クラスを使用する必要があるため、それらを見つけることができます。

これも改善したいと思いますが、私にとっては十分に機能します。:)

于 2010-07-29T13:31:53.733 に答える