この記事では、プラグイン(メインアプリケーションに簡単にインストールして機能を拡張できるソフトウェアモジュール)に焦点を当てます。 より正確には、プラグイン自体ではなく、「アプリケーション-プラグイン」対話システムをプログラムに実装する方法についてです。
ネットワーク上では、そのようなシステムをプログラムコードに統合するための非常に複雑で、時には混乱を招くアルゴリズムを簡単に見つけることができますが、Pythonプログラミング言語を使用するため、すべてがシンプルで非常に明確になります。
しかし、読者にそのプラグインシステムのすべてのツールを示す前に-私の意見ではすべての自尊心のポケット、申し訳ありませんが、プログラムにあるべき一種のペンナイフ-少しの背景...
かつて、私のプロジェクトには、非常に重要な機能が1つだけ必要でしたが、残念ながら、開発段階ではそれを予測できませんでした。 このプロジェクトは大きくてかなり古かったので、不足している機能を実装するプログラムメニューの切望されたボタンを切るために必要なクラスと手順をコードで探して、1週間いじくりまわす必要がありました。 そして、率直に言って、すべてではないにしても、アプリケーションの一部を書き換えることにはほとんど喜びがありません。
その後、プロジェクトのアーキテクチャを確認することを固く決心し、同じレーキを踏まないように、タスクを設定しました。プログラムの機能をワンクリックで拡張する必要があります。 すぐに言ってやった。
したがって、キャビネットから、次のような新しいアプリケーションのスケルトンを取得します。
そして彼の骨を数えます:
Libsフォルダーは、将来のプロジェクトのライブラリーおよびモジュール用です。 現時点では、プラグインを初期化および接続するためのモジュールが含まれています。
loadplugin.py-プロジェクトのルートディレクトリのPluginsフォルダ(自動的に作成されます)からプログラムプラグインをロードします。
manifest.py-ロードされたプラグインのマニフェストを記述するクラス。
プロジェクトのルートディレクトリで:
program.py - Programクラスにあるメインアプリケーションプログラムコード。
main.py-プログラムコードprogram.pyを実行し、プラグインがあればそれを接続します。
次に、プラグインシステムの実装の重要な瞬間のみを説明し、プラグインの操作を示すための最も単純なアプリケーションインターフェイスの作成を省略します。 記事の最後にあるリンクから、サンプル付きの小さなアーカイブをダウンロードできます。
main.py:
#! /usr/bin/python2.7 # -*- coding: utf-8 -*- import traceback __version__ = "0.0.1" def main(): try: from Libs.loadplugin import loadplugin # from program import Program # app = Program() loadplugin(app) # app.run() # except Exception as exc: print traceback.format_exc() traceback.print_exc(file=open("error.log", "w")) # . if __name__ "__main__": main()
Main.pyモジュールアルゴリズム:
- アプリクラスProgramのインスタンスを作成し、それをプラグインダウンロード関数に渡します(このインスタンスはすべてのプラグインで利用でき、 プログラムクラスのメインプログラムコードで実装された変数と関数にアクセスできます)。
- プラグインをダウンロードします。
- アプリケーションを起動します。
- プログラムの起動時に発生したエラーテキストがあるウィンドウが表示されます。
loadplugin.py:
# -*- coding: utf-8 -*- import os import traceback def loadplugin(app): """ . :type app: <class 'program.Program'>; :param app: Program; """ # . plugins_path = \ "{}/Plugins".format(os.path.split(os.path.abspath(sys.argv[0]))[0]) # . plugin_list = \ eval(open("{}/plugins_list.list".format(plugins_path)).read()) for name in os.listdir(plugins_path): if name.startswith("__init__."): continue path = os.path.join(plugins_path, name) if not os.path.isdir(path): continue try: if name in plugin_list: execfile(os.path.join(path, '__init__.py'), {"app": app, "path": path}) except Exception: raise Exception(traceback.format_exc())
loadplugin.pyモジュールのアルゴリズム:
- プラグインパッケージの存在についてプラグインディレクトリ(パッケージ)をスキャンします( プラグインフォルダー内のPythonパッケージはすべてプラグインと見なされます)。
- Pluginsディレクトリにあるplugins_list.listファイルからプラグインのリストを初期化します。
- 見つかったプラグインがこのリストに記載されている場合、接続します。それ以外の場合は、次のプラグインを探しています。
より明確にするために、 loadplugin.pyモジュールからプラグイン検証を削除し、 Pluginsディレクトリ、 plugins_list.listファイルなどがないことを確認するためのさまざまなチェックを削除しました。
お気づきのとおり、プラグインはexecfile関数によって実行されます。
execfile(os.path.join(path, '__init__.py'), {"app": app, "path": path})
プラグインパッケージのinit .pyファイルのコードを実行し、 アプリケーションのメインクラスのアプリインスタンスをグローバル名前空間init .pyに渡します。
さらに、 appを介して、プラグインはアプリケーションプログラムコードのすべての関数と変数にアクセスします。 とても簡単です。
それでは、言葉から行動に移り、 TestPluginフォルダーからテストケース( main.py )を実行しましょう。
ここでは、主にKivyフレームワークを使用して作成していると言っておく価値があります。したがって、テストケースを実行するには、必要なすべてのライブラリがワークステーションにインストールされていることを前提としています。
したがって、例を実行すると、画面の下部にアクションバーがあるシンプルなインターフェイスが表示されます。 右下のボタンを選択し、2つの項目のドロップダウンリストを開き、 「プラグイン」項目をクリックして、 「プラグインがインストールされていません」というメッセージを読みます。
実際、プロジェクトフォルダーを見ると、新しいディレクトリPluginsがあります。
既知のファイルに加えて、プラグインのディレクトリは空です。 じゃあ! それらをインストールする時間です。 プラグインの助けを借りてペンナイフのツールキットを拡張し、アクションバーにHabrロゴを持つ新しいボタンを追加しましょう。
テストケースを含むアーカイブには、 TestPluginsプロジェクトに加えて、 Pluginsフォルダーがあります。 それを開き、 HabraButtonプラグインをプラグインディレクトリ内のプロジェクトにコピーします。
テストアプリケーションを再度実行し、[ プラグイン]アイテムを選択します。
やった! 私たちのペンナイフは、約束どおり、ワンクリックで新しいツールを入手しました。
新しいプラグインの名前のアイテムは黄色で点灯します。これは、アプリケーションが認識したものの、使用するために接続しなかったことを意味します。 これを修正するには、見つかったプラグインのボタンをクリックします。
プラグインを接続し、「プラグインは接続されており、次回起動後にプロジェクトにインポートされます」というメッセージを読みます。
ドロップダウンリストで[プラグイン]を再度選択すると、プラグインが正常に接続されていることがわかります。これは、すでに青色に点灯しているボタンで証明されています。
実際、「接続」項目を選択するとどうなりましたか? プラグイン名は、 Pluginsディレクトリのplugins_list.listファイルで使用可能なリストに追加されました。 これで、プラグインロードモジュールloadplugin.pyがこのプラグインをインポートできるようになります。
これを確認して、テストケースを再度実行してみましょう。
Habrロゴ付きの新しいボタンがアクションバーに表示されました。 それをクリックして、メッセージ「Hello、plugin」をお楽しみください!
実際、それがすべてです。
この記事ではプラグインのコードを考慮していません(非常に単純です)。 HabraButtonパッケージのinit .pyファイルを開き、 アプリインスタンスを介してプラグインがProgramクラスのプログラムコードオブジェクトにアクセスする方法を確認できます。 また、私はプラグイン検証を船外に残しました。 互換性を追跡し、プラグイン情報を視覚化するために必要です。 これはすべてテストケースに含まれています。
お役に立てば幸いです!
テスト例 -40.65 Kb。