(機械翻訳) Zopeコンポーネントアーキテクチャの使用:app: Pyramid¶
フードの下では、:app: `Pyramid`は:term:`アプリケーションレジストリ 'として:term: `Zope Component Architecture`コンポーネントレジストリを使用します。 Zopeコンポーネントアーキテクチャは、「ZCA」と呼ばれています。
伝統的なZopeアプリケーションのデータにアクセスするために使用される `` zope.component`` APIは不透明です。たとえば、従来のZopeアプリケーションでは、:func: `zope.component.getUtility`グローバルAPIを使用する典型的な"無名ユーティリティ"ルックアップがあります。
1 2 3 | from pyramid.interfaces import ISettings
from zope.component import getUtility
settings = getUtility(ISettings)
|
このコードが実行されると、 `` settings``はPython辞書になります。しかし、「市民」はコードを気軽に読んでこれを理解することはできないだろう。開発者が `` zope.component.getUtility`` APIを使うと、普通のコードリーダーの概念的な負荷が高くなります。
ZCAは、app: Pyramid`のような*フレームワークを構築するための優れたツールですが、 zope.componentの不透明さのために*アプリケーション*を構築するのに必ずしも最適なツールではありません` APIs。したがって、:app: `Pyramid`は、アプリケーション開発者からZCAの存在を隠す傾向があります。 app: `Pyramid`アプリケーションを作成するためにZCAを理解する必要はありません。その使用は効果的にフレームワーク実装の詳細です。
しかし、既に:term: Zope`アプリケーションを作成するのに慣れている開発者は、:app: Pyramid`アプリケーションを構築しながらZCAを使用したいことがあります。 :app: `Pyramid`はこれを可能にします。
:app: `Pyramid`アプリケーションでZCAグローバルAPIを使用する¶
:term: `Zope`は、同じPythonプロセスで動作するすべてのZopeアプリケーションに対して、単一のZCAレジストリ(グローバルなZCAレジストリ)を使用するため、1つのプロセスで複数のZopeアプリケーションを実行できなくなります。
ただし、展開を容易にするために、プロセスごとに複数のアプリケーションを実行できることが有用なことがよくあります。たとえば、:term: PasteDeploy " composite "を使用すると、同じプロセスで個々のWSGIアプリケーションを個別に実行できます。それぞれのURL接頭辞の要求に応答します。これにより、例えば、 `` / turbogears``のTurboGearsアプリケーションと `` / pyramid``の `` app: `` Pyramid``アプリケーションを同じterm: `WSGI`サーバを使って起動することができます単一のPythonプロセス内で実行できます。
ほとんどのプロダクションZopeアプリケーションは比較的大きく、Pythonプロセスごとに2つ以上のZopeアプリケーションを実行するためのメモリの制約のために実用的ではありません。しかし、a:app: Pyramid`アプリケーションは非常に小さく、メモリをほとんど消費しないので、プロセスごとにapp: Pyramid`アプリケーションを複数実行することが合理的な目標です。
複数の:app: Pyramid`アプリケーションを1つのプロセスで実行できるようにするには、:app: Pyramid`はデフォルトでアプリケーションごとに別々のZCAレジストリ*を使用します。
このサービスは妥当な目標ですが、典型的な:term: Zope`アプリケーションをビルドしてa:app: Pyramid`アプリケーションを構築するために使用するパターンを使用しようとすると、いくつかの問題が発生します。特別な助けがなければ、:func: zope.component.getUtility`や:func: zope.component.getSiteManager`などのZCA "グローバル" APIは、ZCA "グローバル"レジストリを使用します。したがって、これらのAPIは、:app: Pyramid`アプリケーションで使用されたときに失敗するように見えます。これは、あなたの:app: Pyramid`アプリケーションに関連するコンポーネントレジストリではなく、ZCAグローバルレジストリを参照するためです。
これを修正するには、:meth: pyramid.config.Configurator.hook_zca`を使用するか、起動時に:term: Configurator`コンストラクタにZCAグローバルレジストリを渡すことによって、ZCAグローバルAPIを完全に無効にする方法があります。このセクションでは、3つの方法すべてについて説明します。
グローバルZCA APIの廃止¶
`` zope.component.getSiteManager``、 `` zope.component.getUtility``、:func: zope.component.getAdapter、::func:` zope.componentのようなZCA "グローバル" API関数です。 getMultiAdapter`は厳密には必要ではありません。すべてのコンポーネントレジストリには、同じ機能を提供するメソッドAPIがあります。代わりに使用することができます。たとえば、以下の `` registry``値がZope Component Architectureのコンポーネントレジストリであると仮定すると、以下のコードは `` zope.component.getUtility(IFoo) ``に相当します:
registry.getUtility(IFoo)
完全なメソッドAPIは、 `` zope.component``パッケージに記述されていますが、大体"グローバル" APIをほぼ正確に反映しています。
代わりに"グローバル" ZCA APIを廃止し、代わりにレジストリのメソッドインタフェースを使用する場合は、:app: `Pyramid`コンポーネントレジストリの取得方法だけが必要です。
これを行うには2通りの方法があります:
- app: Pyramid`ビューまたはリソースコード内で:func: pyramid.threadlocal.get_current_registry`関数を使用してください。これは常に"現在の::app:` Pyramid`アプリケーションレジストリを返します。
- :app: Pyramid`のビューコードで、 request.registry``のように registry``という名前の:term: request`オブジェクトの属性を使います。これは、running:app: `Pyramid`アプリケーションに関連するZCAコンポーネントレジストリです。
func: pyramid.threadlocal.get_current_registry`の詳細については、ref: threadlocals_chapter`を参照してください。
`` hook_zca``を使ってZCAグローバルAPIを有効にする¶
app: `Pyramid`スタートアップコード:
1 2 3 4 5 6 | from pyramid.config import Configurator
def app(global_settings, **settings):
config = Configurator(settings=settings)
config.include('some.other.package')
return config.make_wsgi_app()
|
上記の `` app``関数が実行されると、a:term: Configurator`が構築されます。コンフィギュレータが作成されると、* new::term: `application registry`(ZCAコンポーネントレジストリ)が作成されます。新しいレジストリは、 ` registry``引数が省略された場合、a:term: Configurator`コンストラクタが呼び出された場合、または None``の値を持つ `registry``引数が:term: `Configurator`コンストラクタです。
要求中、コンフィギュレータによって作成されたアプリケーションレジストリは"made current "です。これは、要求を処理するスレッドの:func: `〜pyramid.threadlocal.get_current_registry`への呼び出しが、アプリケーションに関連するコンポーネントレジストリを返すことを意味します。
結果として、アプリケーション開発者は `` get_current_registry``を使ってレジストリを取得し、per:ref: disusing_the_global_zca_api`のようにユーティリティなどにアクセスすることができます。しかし、彼らはまだグローバルZCA APIを使用することはできません。 ZCAのグローバルAPIは特別な処理をしなければ、常にグローバルなZCAレジストリ( ` zope.component.globalregistry.base``のもの)を返します。
これを修正してZCAグローバルAPIに"現在の:app:` Pyramid`レジストリを使用させるには、セットアップコード内で:meth: `〜pyramid.config.Configurator.hook_zca`を呼び出す必要があります。例えば:
1 2 3 4 5 6 7 | from pyramid.config import Configurator
def app(global_settings, **settings):
config = Configurator(settings=settings)
config.hook_zca()
config.include('some.other.application')
return config.make_wsgi_app()
|
元のスタートアップコードの行番号5に、 `` config.hook_zca() ``を呼び出す行を追加しました。フードの下のこの行の効果は、次のコードのアナログが実行されることです。
1 2 3 | from zope.component import getSiteManager
from pyramid.threadlocal import get_current_registry
getSiteManager.sethook(get_current_registry)
|
これにより、ZCAグローバルAPIは、:app: Pyramid`アプリケーションレジストリを、:app: Pyramid`要求を実行しているスレッドで使用し始めます。
`` hook_zca``を呼び出すことは、通常は:app: `Pyramid`アプリケーション内でグローバルZCA APIを使用できるという問題を修正するには十分です。ただし、同じプロセスで実行されているZopeアプリケーションが、Zopeグローバルレジストリの代わりに:app: `Pyramid`グローバルレジストリを使用して元の問題を効果的に反転させることも意味します。このような場合は、次のセクション:ref: `using_the_zca_global_registry`の手順に従ってください。
ZCAグローバルレジストリを使用してZCAグローバルAPIを有効にする¶
:app: `Pyramid`アプリケーションに、起動時に新しいレジストリを作成する代わりにZCAグローバルレジストリを使用するよう指示できます:
1 2 3 4 5 6 7 8 9 | from zope.component import getGlobalSiteManager
from pyramid.config import Configurator
def app(global_settings, **settings):
globalreg = getGlobalSiteManager()
config = Configurator(registry=globalreg)
config.setup_registry(settings=settings)
config.include('some.other.application')
return config.make_wsgi_app()
|
上の行5,6、および7は興味深いものです。 5行目は、グローバルZCAコンポーネントレジストリを取得します。 6行目はa:term: Configurator`を作成し、グローバルZCAレジストリをそのコンストラクタに `registry``引数として渡します。 7行目は、ピラミッド固有の登録を持つグローバルレジストリを "設定"します。これは、レジストリが作成されるのではなく構築されたときに通常実行されるコードですが、明示的なレジストリを渡すときに"手で"呼び出す必要があります。
この時点で、:app: `Pyramid`は新しいアプリケーション固有のレジストリを作成するのではなく、ZCAグローバルレジストリを使用します。デフォルトではZCAグローバルAPIはこのレジストリを使用するため、グローバルZCA APIを使用するときにZopeアプリケーションで期待されるように機能します。