web-dev-qa-db-ja.com

Pythonエントリポイントを説明しますか?

PylonsのEggエントリポイントとPeakページのドキュメントを読みましたが、まだよくわかりません。誰かが私にそれらを説明できますか?

164
Brad Wright

「エントリポイント」は通常、開発者またはPythonパッケージのユーザーが使用する可能性がある関数(またはその他の呼び出し可能な関数のようなオブジェクト)ですが、呼び出し不可能なオブジェクトをエントリとして提供できます(コメントで正しく指摘されているように!).

最も一般的な種類のエントリポイントは、「console_script」エントリポイントです。これは、パッケージをインストールするユーザーがコマンドラインツールとして使用できるようにする機能を指します。これは次のようにsetup.pyに入ります:

entry_points={
    'console_scripts': [
        'cursive = cursive.tools.cmd:cursive_command',
    ],
},

「cursive.tools」という展開したばかりのパッケージがあり、コマンドラインから実行できる「筆記体」コマンドを利用できるようにしたかったのです。

$ cursive --help
usage: cursive ...

これを行う方法は、cursive/tools/cmd.pyの「cursive_command」関数のような関数を定義することです。

def cursive_command():
    args = sys.argv[1:]
    if len(args) < 1:
        print "usage: ..."

などなど。コマンドラインから呼び出されたと仮定し、ユーザーが提供した引数を解析し、...コマンドが実行するように設計されていることをすべて実行する必要があります。

docutils パッケージをインストールすると、エントリポイントの使用例として優れた例が得られます。Pythonドキュメントを他の形式に変換するための便利なコマンドのようなものがインストールされます。

150
Brandon Rhodes

EntryPoints 永続的なファイルシステムベースのオブジェクト名登録と名前ベースの直接オブジェクトインポートメカニズムを提供します( setuptools パッケージで実装)。

Pythonオブジェクトの名前を自由形式の識別子に関連付けます。したがって、同じPythonインストールを使用し、識別子を知っている他のコードは、オブジェクトが定義されている場所に関係なく、関連付けられた名前を持つオブジェクトにアクセスできます。 関連付けられた名前は、Python moduleに存在する任意の名前にすることができます。たとえば、クラス、関数、または変数の名前。エントリポイントメカニズムは、インポート可能な限り、名前が何を指すかを気にしません。

例として、関数(の名前)と、完全修飾名「myns.mypkg.mymodule」を持つ架空のpythonモジュールを使用してみましょう。

def the_function():
   "function whose name is 'the_function', in 'mymodule' module"
   print "hello from the_function"

エントリポイントは、setup.pyのエントリポイント宣言を介して登録されます。 「my_ep_func」というエントリポイントの下にthe_functionを登録するには:

    entry_points = {
        'my_ep_group_id': [
            'my_ep_func = myns.mypkg.mymodule:the_function'
        ]
    },

例が示すように、エントリポイントはグループ化されます。グループに属するすべてのエントリポイントを検索するための対応するAPIがあります(以下の例)。

パッケージのインストール時に(つまり、 'python setup.py install'を実行すると)、上記の宣言はsetuptoolsによって解析されます。次に、解析された情報を特別なファイルに書き込みます。その後、 pkg_resources API (setuptoolsの一部)を使用して、エントリポイントを検索し、関連付けられた名前でオブジェクトにアクセスできます。

import pkg_resources

named_objects = {}
for ep in pkg_resources.iter_entry_points(group='my_ep_group_id'):
   named_objects.update({ep.name: ep.load()})

ここで、setuptoolsは特殊ファイルに書き込まれたエントリポイント情報を読み取ります。 pkg_resources.load()の呼び出し時に、エントリポイントを見つけ、モジュール(myns.mypkg.mymodule)をインポートし、そこで定義された関数を取得しました。

同じグループIDの他のエントリポイント登録がないと仮定すると、the_functionの呼び出しは簡単になります。

>>> named_objects['my_ep_func']()
hello from the_function

したがって、最初は少し理解しにくいかもしれませんが、エントリポイントメカニズムは実際には非常に簡単に使用できます。プラグ可能なPythonソフトウェア開発に役立つツールを提供します。

178
Petri

抽象的観点から、エントリポイントは、特定のインターフェイスを実装するPython呼び出し可能オブジェクトのシステム全体のレジストリを作成するために使用されます。 pkg_resourcesには、特定のパッケージによってアドバタイズされるエントリポイントを確認するAPIと、特定のエントリポイントをアドバタイズするパッケージを決定するAPIがあります。

エントリポイントは、あるパッケージが別のパッケージにあるプラグインを使用できるようにするのに役立ちます。たとえば、Ian Bickingの Paste プロジェクトはエントリポイントを広範囲に使用します。この場合、エントリポイントpaste.app_factoryを使用して、WSGIアプリケーションファクトリをアドバタイズするパッケージを作成できます。

エントリポイントのもう1つの用途は、プラグイン機能を提供するシステム上のすべてのパッケージを列挙することです。 TurboGears Webフレームワークは python.templating.engines エントリポイントを使用して、インストールされ利用可能なテンプレートライブラリを検索します。

16
Rick Copeland