Zope ユーティリティの ZCML 登録がコンポーネントまたはファクトリを受け入れることができるのは、少し混乱しています。
<utility component=".some.Class" />
対
<utility factory=".some.Factory" />
違いはなんですか?
Zope ユーティリティの ZCML 登録がコンポーネントまたはファクトリを受け入れることができるのは、少し混乱しています。
<utility component=".some.Class" />
対
<utility factory=".some.Factory" />
違いはなんですか?
@lennart-regebroの答えは、意図せずに少し欺瞞的かもしれないと思います。Zope のドキュメントは少し曖昧なので理解できます。以下は正しい解釈だと思いますが、確認するために自分でテストする必要がありました。
コンポーネントとファクトリ登録の両方で、最初の登録後に getUtility を呼び出すたびに、同じインスタンスが返されます。
違いは、コンポーネント メソッドは、参照されるオブジェクトを返されるユーティリティ インスタンスとして登録するのに対し、ファクトリ メソッドは、参照されるオブジェクトを呼び出し、返されるユーティリティ インスタンスとして結果を格納することです。
たとえば、次のように定義されたユーティリティ クラスがあるとします。
class MyUtility(object):
implements(IMyUtility)
...
それを登録する;
<utility factory=".my_module.MyUtility"/>
zcml が実行された時点で、MyUtility のインスタンスが作成され、今後の getUtility の呼び出しのために保存されます。
> a = getUtility(IMyUtility)
> b = getUtility(IMyUtility)
> c = getUtility(IMyUtility)
> a is b is c
True
ファクトリをクラスではなく関数として登録できたことに注意してください。引数なしで呼び出されたときに、使用するユーティリティのインスタンスを返すものでなければなりません。
コンポーネントを使用した同等の例は次のとおりです。
class MyUtility(object):
implements(IMyUtility)
...
my_module_instance_of_utility = MyUtility()
それを登録する;
<utility component=".my_module.my_module_instance_of_utility"\>
これは、ファクトリの例とほぼ同じです。唯一の違いは、コンポーネントの例で返されたインスタンスは、my_module
(登録メカニズムを含む) 何かによってインポートされたときにインスタンス化されることです。一方、ファクトリを使用する場合、zcml 構成が実行されるとインスタンスが登録される直前にインスタンス化されます。どちらの場合も、その後 getUtility を呼び出すと、同じインスタンスが返されます。
これを IFactory と混同しないでください。IFactory は、要求されるたびに新しいインスタンスを提供できるものを提供しますが、API はわずかに異なります。これらの詳細については、このドキュメントを参照してください。
ファクトリはユーティリティを作成しますが、コンポーネントとして登録されたユーティリティはインスタンスです。したがって、コンポーネントとして登録されたユーティリティを検索すると、毎回同じオブジェクトが返されます。ただし、ファクトリとして登録されている場合は、毎回新しいインスタンスを取得します。