Pregunta

Me han empezado a utilizar las interfaces de Zope en mi código, ya partir de ahora, son realmente única documentación. Las uso para especificar qué atributos de la clase debe poseer, aplicar de forma explícita en las clases correspondientes y comprobar explícitamente para ellos donde espero una. Esto está muy bien, pero me gustaría que hagan más si es posible, como en realidad verificar que la clase ha implementado la interfaz, en lugar de simplemente verificar que he dicho que implementa la interfaz de clase. He leído el zope wiki un par de veces, pero todavía no puedo ver mucho más el uso de las interfaces que lo que estoy haciendo actualmente. Por lo tanto, mi pregunta es ¿qué más se puede utilizar para estas interfaces, y cómo se les utilice para más.

¿Fue útil?

Solución

En realidad se puede comprobar si el objeto o la clase implementa la interfaz. Para que pueda utilizar el módulo verify (se suele utilizar en las pruebas):

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

Interfaces también se puede utilizar para configurar y probar invariantes. Puede encontrar más información aquí:

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

Otros consejos

Donde trabajo, utilizamos interfaces de modo que podemos utilizar ZCA, o la href="http://www.muthukadan.net/docs/zca.html" rel="noreferrer"> arquitectura de componentes de Zope , que es todo un marco para la fabricación de componentes que son intercambiables y conectables utilizando Interfaces. Utilizamos ZCA para que podamos hacer frente a todo tipo de personalizaciones por cliente sin necesidad de tener que desembolsar nuestro software o tener todos los muchos bits por cliente que ensucian el árbol principal. El wiki Zope es a menudo bastante incompleta, por desgracia. Hay una explicación buena, pero-escueto de la mayor parte de las características de ZCA en su de ZCA página PyPI .

No consumo Interfaces para nada como la comprobación de que una clase implementa todos los métodos para una Interface dado. En teoría, eso puede ser útil cuando se agrega otro método a una interfaz, para comprobar que ha recordado que añadir el nuevo método a todas las clases que implementan la interfaz. Personalmente prefiero fuertemente para crear un nuevo Interface sobre la modificación de una vieja. Modificó el antiguo Interfaces es por lo general una muy mala idea una vez que están en los huevos que han sido liberados a PyPI o para el resto de su organización.

Una nota rápida sobre la terminología: clases implementan Interfaces, y objetos (instancias de clases) proporcionar Interfaces. Si desea comprobar si existe una Interface, lo haría bien ISomething.implementedBy(SomeClass) escritura o ISomething.providedBy(some_object).

Por lo tanto, hasta ejemplos en los que ZCA es útil. Supongamos que estamos escribiendo un blog, utilizando la ZCA para que sea modular. Tendremos un objeto BlogPost para cada puesto, lo que proporcionará una interfaz IBlogPost, todos definidos en nuestro práctico-excelente huevo my.blog. También vamos a almacenar la configuración del blog en el BlogConfiguration objetos que proporcionan IBlogConfiguration. Usando esto como punto de partida, podemos implementar nuevas características sin necesidad de tener que tocar my.blog en absoluto.

La siguiente es una lista de ejemplos de cosas que podemos hacer mediante el uso de ZCA, sin tener que alterar el huevo my.blog base. Yo o mis compañeros de trabajo he hecho todas estas cosas (y las encontraron útil) en proyectos reales para-cliente, aunque no estábamos implementando los blogs en el momento. :) Algunos de los casos de uso aquí podría ser mejor resueltos por otros medios, como por ejemplo un archivo CSS de impresión.

  1. La adición de puntos de vista adicionales (por lo general, BrowserViews registrados en ZCML con la directiva browser:page) a todos los objetos que proporcionan IBlogPost. Podría hacer un huevo my.blog.printable. Ese huevo registraría un BrowserView llamada print para IBlogPost, lo que hace que la entrada de blog a través de un Zope plantilla de página diseñado para producir HTML que imprime muy bien. BrowserView que aparecería entonces en el /path/to/blogpost/@@print URL.

  2. El mecanismo de suscripción de eventos en Zope. Digamos que quiero publicar los canales RSS, y yo quiero generar por adelantado en lugar de por encargo. Podría crear un huevo my.blog.rss. En ese huevo, me inscribo a un abonado para los eventos que proporcionan IObjectModified (zope.lifecycleevent.interfaces.IObjectModified), en los objetos que proporcionan IBlogPost. Ese abonado conseguiría llamará cada vez que un atributo cambia en nada proporcionando IBlogPost, y pude utilizarlo para actualizar todos los canales RSS que el blog debe aparecer en.

    En este caso, podría ser mejor tener un evento IBlogPostModified que se envía al final de cada una de las entradas del blog BrowserViews que modificar, ya que se obtiene IObjectModifiednt una vez en cada cambio de atributo -. que podría ser demasiado a menudo por el bien de rendimiento

  3. adaptadores. Los adaptadores son efectivamente "moldes" de una interfaz a otra. Para la programación de los frikis del lenguaje: adaptadores Zope implementan "abierta" múltiple de despacho en Python (por "abierta" me refiero a "puede agregar más casos de cualquier huevo"), con partidos interfaz más específicos teniendo prioridad sobre los partidos menos específicas (Interface las clases pueden ser subclases de unos a otros, y esto es exactamente lo que usted esperaría que lo haría.)

    Adaptadores de una Interface se puede llamar con una sintaxis muy agradable, ISomething(object_to_adapt), o se puede consultar a través de la zope.component.getAdapter función. Adaptadores de múltiples Interfaces han de ser consultados a través de la zope.component.getMultiAdapter función, que es un poco menos bonito.

    Puede tener más de un adaptador para un conjunto dado de Interfaces, diferenciados por un name cadena que usted proporciona cuando se registra el adaptador. El nombre por defecto es "". Por ejemplo, BrowserViews son en realidad los adaptadores que se adaptan a la interfaz que están registradas en y una interfaz que los HTTPRequest implementa la clase. También puede mirar hacia arriba todos de los adaptadores que se registran a partir de una secuencia a otra Interfaces Interface, utilizando zope.component.getAdapters( (IAdaptFrom,), IAdaptTo ), que devuelve una secuencia de (nombre, adaptador de pares). Esto puede ser usado como una forma muy agradable para proporcionar ganchos para los plugins para adherirse a.

    Decir que quería salvar a todos los mensajes y la configuración de mi blog como un gran archivo XML. Creo un huevo my.blog.xmldump que define una IXMLSegment, y registra un adaptador de IBlogPost a IXMLSegment y un adaptador de IBlogConfiguration a IXMLSegment. Ahora puedo llamar a cualquier adaptador es apropiado para un objeto que desea realizar una serie escribiendo IXMLSegment(object_to_serialize).

    Incluso podría añadir más adaptadores de varias otras cosas que IXMLSegment de huevos distintos de my.blog.xmldump. ZCML tiene una característica que pueda realizar una directiva particular, si y sólo si se ha instalado un poco de huevo. Podría utilizar esto para tener my.blog.rss registrar un adaptador de IRSSFeed a IXMLSegment si y sólo si my.blog.xmldump que se encuentren instaladas, sin hacer my.blog.rss dependerá de my.blog.xmldump.

  4. Viewlets son como pequeños BrowserViews que se puede tener 'suscribir' a un punto en particular dentro de una página. No puedo recordar todos los detalles en este momento, pero estos son muy buenos para cosas como plugins que desea que aparezca en una barra lateral.

    No puedo recordar la ligera si son parte de la base de Zope o Plone. Yo recomendaría contra el uso de Plone a menos que el problema que se está tratando de resolver realmente necesita un verdadero CMS, ya que es una pieza grande y complicado de software y tiende a ser un poco lento.

    Usted no necesariamente necesita realmente Viewlets todos modos, ya BrowserViews puedan llamarse entre sí, ya sea mediante el uso de '/ @@ some_browser_view objeto' TAL en una expresión, o mediante el uso de queryMultiAdapter( (ISomething, IHttpRequest), name='some_browser_view' ), pero son bastante agradable sin tener en cuenta.

  5. Interfaces Marker. A Interface marcador es un Interface que no proporciona métodos y atributos. Puede añadir un marcador de Interface cualquier objeto en tiempo de ejecución utilizando ISomething.alsoProvidedBy. Esto le permite, por ejemplo, el alter qué adaptadores se acostumbrará en un objeto particular, y que BrowserViews se definirá en él.

Me disculpo que no he entrado en detalles suficientes para poder llevar a cabo cada uno de estos ejemplos de inmediato, sino que tomaría aproximadamente una entrada de blog cada uno.

interfaces de Zope puede proporcionar una forma útil para desacoplar dos piezas de código que no debe depender de uno al otro.

Supongamos que tenemos un componente que sabe cómo imprimir un saludo en a.py módulo:

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

Y un código que necesita imprimir un saludo en b.py módulo:

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

Esta disposición hace que sea difícil que cambiar el código que maneja el saludo sin tocar b.py (que podría ser distribuido en un paquete separado). En lugar de ello, podríamos introducir tercera c.py módulo que define una interfaz IGreeter:

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

Ahora podemos usar esto para desacoplar a.py y b.py. En lugar de crear instancias de una clase Greeter, b.py ahora pedir una utilidad que proporciona la interfaz IGreeter. Y a.py declarará que implementa el interfaz de la clase Greeter que:

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

Nunca he usado interfaces de Zope, pero es posible que no hacer una metaclase , que en los cheques de inicialización de los miembros de la clase en contra de la interfaz, y plantea una excepción de tiempo de ejecución si no se implementa un método.

Con Python que no tienen otras opciones. O bien tienen un paso "compilación" que inspecciona su código, o dinámicamente en tiempo de ejecución inspeccionarlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top