質問

私はコード内で Zope インターフェースを使い始めましたが、現時点では、それらは実際には単なるドキュメントです。これらを使用して、クラスが所有する必要がある属性を指定し、それらを適切なクラスに明示的に実装し、必要な場合にはそれらを明示的にチェックします。これはこれで問題ありませんが、クラスがインターフェイスを実装していると述べたことを単に検証するのではなく、クラスがインターフェイスを実装していることを実際に検証するなど、可能であればさらに多くのことを行ってもらいたいと思います。私は zope wiki を何度か読みましたが、現在私が行っていること以上にインターフェイスを使用する方法はまだ見つかりません。そこで、私の質問は、これらのインターフェイスを他に何に使用できるのか、さらにどのように使用できるのかということです。

役に立ちましたか?

解決

あなたのオブジェクトまたはクラスがあなたのインターフェイスを実装している場合、

あなたは、実際にテストをすることができます。

:あなたは(あなたが通常あなたのテストでそれを使用する)verifyモジュールを使用することができることについては
>>> from zope.interface import Interface, Attribute, implements
>>> class IFoo(Interface):
...     x = Attribute("The X attribute")
...     y = Attribute("The Y attribute")

>>> class Foo(object):
...     implements(IFoo)
...     x = 1
...     def __init__(self):
...         self.y = 2

>>> from zope.interface.verify import verifyObject
>>> verifyObject(IFoo, Foo())
True

>>> from zope.interface.verify import verifyClass
>>> verifyClass(IFoo, Foo)
True

インターフェースも不変量を設定し、テストするために使用することができます。 あなたがここでより多くの情報を見つけることができます:

http://www.muthukadan.net/docs/zca.html#interfaces

他のヒント

私の職場では、ZCA を使用できるようにインターフェイスを使用しています。 Zope コンポーネントのアーキテクチャ, 、これは、交換可能でプラグイン可能なコンポーネントを作成するためのフレームワーク全体です。 Interfaces.ZCA を使用することで、必ずしもソフトウェアをフォークしたり、クライアントごとの多数のビットでメイン ツリーを混乱させたりする必要がなく、クライアントごとのあらゆる種類のカスタマイズに対応できます。残念ながら、Zope wiki は非常に不完全であることがよくあります。ZCA の機能のほとんどについては、わかりやすく簡潔に説明されています。 ZCAのpypiページ.

使いません Interfaceクラスが指定されたメソッドのすべてのメソッドを実装しているかどうかをチェックするなどの用途に使用します。 Interface. 。理論的には、これは、インターフェイスに別のメソッドを追加するときに、そのインターフェイスを実装するすべてのクラスに新しいメソッドを追加したことを忘れていないことを確認するのに役立つ可能性があります。個人的には、新しいものを作成することを強く好みます Interface 古いものを修正しすぎます。古いものを変更する Interfaces pypi や他の組織に放出された卵の中にそれらが含まれると、通常は非常に悪い考えになります。

用語についての簡単なメモ:クラス 埋め込む Interfaceおよびオブジェクト (クラスのインスタンス) 提供する Interfaces.を確認したい場合は、 Interface, 、次のように書きます。 ISomething.implementedBy(SomeClass) または ISomething.providedBy(some_object).

それでは、ZCA が役立つ例を見ていきましょう。ZCA を使用してブログをモジュール化して、ブログを書いているとしましょう。いただきます BlogPost 各投稿のオブジェクト。 IBlogPost インターフェイス、すべてハンディダンディで定義されています my.blog 卵。ブログの設定も保存します BlogConfiguration 提供するオブジェクト IBlogConfiguration. 。これを開始点として使用すると、必ずしも触れることなく新しい機能を実装できます。 my.blog 全然。

以下は、ベースを変更せずに ZCA を使用して実行できることの例のリストです。 my.blog 卵。当時はブログを実装していませんでしたが、私または私の同僚は実際のクライアント向けプロジェクトでこれらすべてのことを実行しました (そして、それらが役立つと感じました)。:) ここでのユースケースの中には、CSS ファイルの印刷など、他の手段でより適切に解決できるものもあります。

  1. 追加のビューの追加 (BrowserViews、通常はに登録されています ZCML とともに browser:page ディレクティブ) を提供するすべてのオブジェクトに IBlogPost. 。作ることができました my.blog.printable 卵。その卵は BrowserView を登録します。 print のために IBlogPost, 、ブログ投稿をレンダリングします。 Zopページテンプレート 適切に印刷される HTML を生成するように設計されています。それ BrowserView URL に表示されます /path/to/blogpost/@@print.

  2. Zope のイベント サブスクリプション メカニズム。RSS フィードを公開したいと考えており、要求に応じて生成するのではなく、事前に生成したいとします。を作成できました my.blog.rss 卵。その卵では、以下を提供するイベントのサブスクライバーを登録します。 IObjectModified (zope.lifecycleevent.interfaces.IObjectModified)、提供するオブジェクトに対して IBlogPost. 。そのサブスクライバは、提供するもので属性が変更されるたびに呼び出されます。 IBlogPost, これを使用して、ブログ投稿が表示されるすべての RSS フィードを更新できます。

    この場合は、あったほうがよいかもしれません。 IBlogPostModified 各イベントの最後に送信されるイベント BrowserViewブログ投稿を変更するため、 IObjectModified 属性が変更されるたびに 1 回送信されますが、パフォーマンスを考慮すると頻度が高すぎる可能性があります。

  3. アダプター。アダプタは、あるインターフェイスから別のインターフェイスに事実上「キャスト」されます。プログラミング言語マニア向け:Zope アダプターは、Python で「オープン」複数ディスパッチを実装します (「オープン」とは、「どの卵からでもケースを追加できる」という意味です)。より具体的なインターフェースの一致が、あまり具体的でない一致よりも優先されます (Interface クラスは互いのサブクラスにすることができ、これはまさに期待通りの動作をします。)

    アダプターを1つから Interface 非常に優れた構文で呼び出すことができます。 ISomething(object_to_adapt), 、または関数経由で検索できます zope.component.getAdapter. 。複数のアダプター Interface関数を介して検索する必要があります zope.component.getMultiAdapter, これは少し美しさが劣ります。

    特定のセットに対して複数のアダプターを使用できます。 Interfaces、文字列で区別 name アダプターの登録時に指定します。名前のデフォルトは、 "". 。例えば、 BrowserViewは実際には、登録されているインターフェイスと HTTPRequest クラスが実装するインターフェイスから適応するアダプターです。調べることもできます 全て の 1 つのシーケンスから登録されたアダプターの数 Interface別のものに Interface, を使用して zope.component.getAdapters( (IAdaptFrom,), IAdaptTo ), 、(名前、アダプター) ペアのシーケンスを返します。これは、プラグインが接続するためのフックを提供する非常に優れた方法として使用できます。

    すべてのブログの投稿と設定を 1 つの大きな XML ファイルとして保存したいとします。私は my.blog.xmldump を定義する卵 IXMLSegment, 、からアダプターを登録します IBlogPostIXMLSegment そしてアダプターは IBlogConfigurationIXMLSegment. 。次のように書くことで、シリアル化したいオブジェクトに適したアダプターを呼び出すことができます。 IXMLSegment(object_to_serialize).

    他のさまざまなものからさらにアダプターを追加することもできます IXMLSegment 卵以外から my.blog.xmldump. 。ZCML には、egg がインストールされている場合に限り、特定のディレクティブを実行できる機能があります。これを使えば my.blog.rss からアダプターを登録します IRSSFeedIXMLSegment もし my.blog.xmldump 作成せずにたまたまインストールされている my.blog.rss による my.blog.xmldump.

  4. Viewletは小さいようなものです BrowserViewページ内の特定の場所を「購読」できるということです。今は詳細をすべて思い出せませんが、これらはサイドバーに表示したいプラグインなどに非常に適しています。

    彼らがベースの Zope の一部なのか Plone の一部なのかは直接思い出せません。解決しようとしている問題に実際に本物の CMS が必要な場合を除き、Plone は使用しないことをお勧めします。Plone は大きくて複雑なソフトウェアであり、速度がやや遅い傾向があるためです。

    実際には必ずしも必要ではありません Viewletとにかく、それ以来 BrowserViewTAL 式で 'object/@@some_browser_view' を使用するか、または queryMultiAdapter( (ISomething, IHttpRequest), name='some_browser_view' ), 、しかし、それにもかかわらず、それらはかなり素晴らしいです。

  5. マーカー Interfaces.マーカー Interface です Interface メソッドも属性も提供しません。マーカーを追加できます Interface 実行時に使用する任意のオブジェクト ISomething.alsoProvidedBy. 。これにより、たとえば、特定のオブジェクトでどのアダプタが使用されるか、およびどのアダプタが使用されるかを変更できます。 BrowserViews が定義されます。

これらの各例をすぐに実装できるほど詳しく説明していないことをお詫びします。ただし、それぞれの例をブログに投稿するのに 1 つほどかかります。

はZopeのインタフェースが互いに依存してはならないコードの二つの部品を分離するための有用な方法を提供することができる。

と言う我々はモジュールa.pyに挨拶を印刷する方法を知っているコンポーネントを持っています

>>> class Greeter(object):
...     def greet(self):
...         print 'Hello'

やニーズがモジュールb.pyで挨拶印刷することをいくつかのコード:

>>> Greeter().greet()
'Hello'

この配置は、それがコードアウトスワップするハードハンドルが(別のパッケージで配布されるかもしれない)接触b.pyずに挨拶することを行います。

:その代わりに、我々はIGreeterインタフェースを定義する第3のモジュールのc.pyを導入することができ
>>> from zope.interface import Interface
>>> class IGreeter(Interface):
...     def greet():
...         """ Gives a greeting. """

今、私たちはデカップルa.pyとb.py.にこれを使用することができます代わりにGreeterクラスをインスタンス化のため、b.pyは今IGreeterインタフェースを提供するユーティリティをお願いします。そしてa.pyは、Greeterクラスの実装を宣言します、そのインタフェースます:

(a.py)
>>> from zope.interface import implementer
>>> from zope.component import provideUtility
>>> from c import IGreeter

>>> @implementer(IGreeter)
... class Greeter(object):
...     def greet(self):
...         print 'Hello'
>>> provideUtility(Greeter(), IGreeter)

(b.py)
>>> from zope.component import getUtility
>>> from c import IGreeter

>>> greeter = getUtility(IGreeter)
>>> greeter.greet()
'Hello'

私は Zope インターフェースを使用したことがありませんが、 メタクラス, 、初期化時にインターフェイスに対してクラスのメンバーをチェックし、メソッドが実装されていない場合は実行時例外を発生させます。

Python には他の選択肢はありません。コードを検査する「コンパイル」ステップを設けるか、実行時にコードを動的に検査します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top