Frage

Ich habe mit Zope Schnittstellen in meinem Code gestartet und ab sofort, sie sind wirklich nur Dokumentation. Ich benutze sie, um anzugeben, was die Klasse Attribute besitzen sollte, ausdrücklich in den entsprechenden Klassen implementieren und für sie explizit prüfen, wo ich zu erwarten. Das ist in Ordnung, aber ich mag sie mehr, wenn möglich zu tun, wie eigentlich die Klasse überprüfen, ob die Schnittstelle implementiert hat, anstatt nur die Überprüfung, dass ich gesagt habe, dass die Klasse implementiert die Schnittstelle. Ich habe das Zope Wiki ein paar Mal gelesen, aber immer noch nicht viel mehr Einsatz für Schnittstellen als sehen, was ich derzeit tue. Also, meine Frage ist, was sonst kann man diese Schnittstellen verwenden, weil und wie verwenden Sie sie für mehr.

War es hilfreich?

Lösung

Sie können testen, tatsächlich, wenn Ihr Objekt oder Klasse implementiert Ihre Schnittstelle. Dafür Sie verify Modul verwenden können (Sie es normalerweise in Ihren Tests verwenden würde):

>>> 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

Schnittstellen kann auch zur Einstellung und Prüfung Invarianten verwendet werden. Sie können mehr Informationen finden Sie hier:

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

Andere Tipps

Wo ich arbeite, verwenden wir Schnittstellen, so dass wir ZCA verwenden können, oder die Zope Component Architecture , die für die Herstellung von Komponenten, die swappable und steckbare mit Interfaces ein ganzen Rahmen ist. Wir verwenden ZCA so, dass wir mit allen Arten von pro-Client-Anpassungen ohne unbedingt unsere Software gabeln oder haben all die vielen pro-Client-Bits vermasselt den Hauptbaum bewältigen kann. Der Zope Wiki ist oft sehr unvollständig, leider. Es gibt eine gute-but-lapidare Erklärung der meisten ZCA-Funktionen auf ihren ZCA der pypi .

Ich habe nicht Interfaces für etwas verwenden wie die Überprüfung, dass eine Klasse implementiert alle Methoden für einen bestimmten Interface. In der Theorie, die vielleicht nützlich sein, wenn Sie eine andere Methode für eine Schnittstelle hinzufügen, um zu überprüfen, dass Sie die neue Methode alle Klassen hinzuzufügen habe daran erinnert, dass die Schnittstelle implementieren. Persönlich bevorzuge ich nachdrücklich empfohlen, einen neuen Interface über Modifizieren eines alten zu erstellen. alt Interfaces Modifizierung ist in der Regel eine sehr schlechte Idee, wenn sie in den Eiern sind, den pypi oder an den Rest Ihrer Organisation veröffentlicht wurde.

Eine kurze Anmerkung zur Terminologie: Klassen implementieren Interfaces und Objekte (Instanzen von Klassen) bietet Interfaces. Wenn Sie möchten, für einen Interface überprüfen, würden Sie entweder schreiben oder ISomething.implementedBy(SomeClass) ISomething.providedBy(some_object).

Also, bis auf Beispiele, wo ZCA ist nützlich. Nehmen wir an, dass wir ein Blog schreiben, die ZCA mit ihm modular zu machen. Wir werden für jede Stelle einen BlogPost Gegenstand haben, die eine IBlogPost Schnittstelle zur Verfügung stellt, die alle in unserem Handy-Dandy my.blog Ei definiert. Wir speichern auch die Konfiguration des Blog in BlogConfiguration Objekte, die IBlogConfiguration liefern. Mit diesem als Ausgangspunkt, können wir neue Funktionen implementieren, ohne notwendigerweise my.blog überhaupt zu berühren.

Im Folgenden ist eine Liste der Beispiele für Dinge, die wir durch die Verwendung ZCA tun können, ohne die Basis my.blog Ei ändern zu müssen. Ich oder meine Mitarbeiter haben all diese Dinge getan (und fand sie nützlich) auf real für Client-Projekte, auch wenn wir nicht wurden Blogs zum Zeitpunkt der Umsetzung. :) Hier sind einige der Anwendungsfälle besser mit anderen Mitteln, wie beispielsweise eine Druck CSS-Datei gelöst werden könnten.

  1. Hinzufügen von zusätzlichen Ansichten (BrowserViews, registriert in der Regel in ZCML mit der browser:page-Richtlinie) auf alle Objekte, die IBlogPost bieten. Ich könnte ein my.blog.printable Ei machen. Das Ei würde eine BrowserView genannt print für IBlogPost registrieren, die die Blog-Post über ein Zope Page Template produziert HTML entwickelt, den Druck schön. Die BrowserView würde dann unter der URL /path/to/blogpost/@@print erscheinen.

  2. Die Veranstaltung Abonnement-Mechanismus in Zope. Sagen wir, ich möchte RSS-Feeds veröffentlichen, und ich möchte, dass sie im Voraus erzeugen, anstatt auf Anfrage. Ich könnte ein my.blog.rss Ei erstellen. In diesem Ei, würde ich einen Teilnehmer für Veranstaltungen registrieren, die IObjectModified bieten (zope.lifecycleevent.interfaces.IObjectModified), auf Objekte, die IBlogPost liefern. Das Teilnehmer würde jedes Mal, wenn ein Attribut geändert auf allem, was die Bereitstellung IBlogPost aufgerufen werden, und ich kann es alle der RSS-Feeds aktualisieren verwenden, dass die Blog-Post erscheint in sollte.

    In diesem Fall könnte es besser sein, ein IBlogPostModified Ereignis zu haben, die am Ende jeder der BrowserViews dass modify Blog-Beiträge gesendet wird, da IObjectModified bekommen sent einmal auf jedes einzelne Attribut ändern -., die für die Leistung willen zu oft sein könnte

  3. Adapter. Adapter sind effektiv „casts“ von einer Schnittstelle zur anderen. Für die Programmierung Sprache Geeks: Zope Adapter „offen“ Multiple-Versand in Python implementieren (durch „offene“ meine ich „Sie mehr Fälle von jedem Ei hinzufügen können“), mit mehr spezifischen Schnittstelle Streichhölzer nehmen Vorrang vor weniger spezifischen Spielen (Interface Klassen können Unterklassen sein ein anderes, und das genau das tut, was hoffen, dass Sie würde es tun würde.)

    Adapter von einer Interface kann mit einer sehr schönen Syntax, ISomething(object_to_adapt) genannt werden, oder es kann über die Funktion zope.component.getAdapter nachgeschlagen werden. Adapter von mehreren Interfaces werden müssen über die Funktion zope.component.getMultiAdapter nachgeschlagen, was ziemlich leicht weniger ist.

    Sie können mehr als einen Adapter für einen bestimmten Satz von Interfaces, durch eine Schnur name differenzierte, dass Sie bei der Registrierung der Adapter. Der Name standardmäßig "". Zum Beispiel BrowserViews sind tatsächlich Adapter, die von der Schnittstelle anzupassen, dass sie sich auf und eine Schnittstelle, dass die Httprequest Klasse implementiert angemeldet sind. Sie können nachschlagen auch alle der Adapter, die von einer Sequenz von Interfaces an einen anderen Interface registriert sind, unter Verwendung von zope.component.getAdapters( (IAdaptFrom,), IAdaptTo ), die eine Folge von (Name, Adapter) Paare zurück. Dies kann als eine sehr schöne Art und Weise verwendet werden, Haken für Plugins zur Verfügung zu stellen, sich heften sich an.

    Say Ich wollte alle meiner Blog-Posts und Konfiguration als eine große XML-Datei speichern. Ich schaffe eine my.blog.xmldump Ei, das eine IXMLSegment definiert und registriert einen Adapter von IBlogPost zu IXMLSegment und einen Adapter von IBlogConfiguration zu IXMLSegment. Ich kann jetzt anrufen je nachdem, welcher Adapter für einen Gegenstand geeignet ist, ich durch das Schreiben IXMLSegment(object_to_serialize) serialisiert werden soll.

    Ich konnte sogar mehr Adapter von verschiedenen anderen Dingen IXMLSegment aus Eiern andere als my.blog.xmldump hinzufügen. ZCML hat eine Funktion, wo es eine bestimmte Richtlinie ausgeführt werden kann, wenn und nur wenn einige Ei installiert ist. Ich konnte dies nutzen haben my.blog.rss einen Adapter von IRSSFeed zu IXMLSegment registrieren iff my.blog.xmldump zu installierenden geschieht, ohne my.blog.rss abhängig machen my.blog.xmldump.

  4. Viewlets sind wie kleine BrowserViews, dass man haben kann ‚subscribe‘ an einer bestimmten Stelle innerhalb einer Seite. Ich kann nicht alle Details im Augenblick erinnern, aber diese sind sehr gut für Dinge wie Plugins, dass Sie in einer Seitenleiste angezeigt werden sollen.

    Ich kann mich nicht erinnern, freihändig, ob sie Teil der Basis Zope oder Plone. Ich würde empfehlen, gegen Plone verwenden, es sei denn das Problem, dass Sie tatsächlich ein echtes CMS muss versuchen zu lösen, da es ein großer und kompliziert ist Teil der Software und es neigt dazu, ein bisschen langsam.

    Sie müssen nicht wirklich brauchen Viewlets sowieso, da BrowserViews sie nennen kann, entweder durch Verwendung von ‚Objekt / @@ some_browser_view‘ in einem TAL-Ausdruck oder durch queryMultiAdapter( (ISomething, IHttpRequest), name='some_browser_view' ) verwenden, aber sie sind ziemlich schön unabhängig.

  5. Marker Interfaces. Ein Marker ist ein Interface Interface die keine Verfahren und keine Attribute bereitstellt. Sie können einen Marker Interface jedes Objekt zur Laufzeit mit ISomething.alsoProvidedBy hinzufügen. So können Sie zum Beispiel Alter, welche Adapter auf ein bestimmtes Objekt gewöhnen und welche BrowserViews auf ihr definiert werden.

Ich entschuldige mich, dass ich nicht in genug Detail gegangen, um der Lage sein, jedem dieser Beispiele sofort zu implementieren, aber sie würden nehmen etwa ein Blog veröffentlichen jeden.

Zope-Schnittstellen können eine nützliche Art und Weise bieten zwei Teile des Codes zu entkoppeln, die nicht voneinander abhängen sollte.

sagen, wir haben eine Komponente, die wissen, wie man in Modul a.py Gruß drucken:

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

Und einige Code, dass der Bedarf einen Gruß in Modul b.py drucken:

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

Diese Anordnung macht es schwer, aus dem Code zu tauschen, dass Griffe die ohne sie zu berühren b.py Gruß (die in einem separaten Paket verteilt werden könnten). Stattdessen könnten wir ein drittes Modul c.py einzuführen, die eine IGreeter Schnittstelle definiert:

>>> from zope.interface import Interface
>>> class IGreeter(Interface):
...     def greet():
...         """ Gives a greeting. """

Jetzt können wir dies zu entkoppeln a.py verwenden und b.py. Statt eine Greeter Klasse instanziiert wird, wird b.py jetzt ein Dienstprogramm fragen die IGreeter Interface. Und a.py wird erklären, dass die Greeter-Klasse implementiert die Schnittstelle:

(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'

Ich habe noch nie Zope-Schnittstellen verwendet, aber Sie könnten erwägen, einen metaclass , die die Mitglieder der Klasse gegen die Schnittstelle bei der Initialisierung überprüft, und wenn eine Methode eine Laufzeitausnahme wirft nicht implementiert ist.

Mit Python Sie haben keine anderen Optionen. Entweder hat einen „Kompilierung“ Schritt, den Code überprüft, oder dynamisch zur Laufzeit überprüfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top