2012-09-22 7 views
6

Estoy tratando de usar el decorador propiedad en una clase. Si bien funciona bien per se, no puedo usar ningún código que tenga que acceder al REQUEST.Zope: no se puede acceder petición en virtud del decorador de la propiedad

class SomeClass(): 
    #Zope magic code 
    _properties=({'id':'someValue', 'type':'ustring', 'mode':'r'},) 

    def get_someValue(self): 
    return self.REQUEST 

    @property 
    def someValue(self): 
    return self.REQUEST 

Aunque llamando get_someValue me consigue el resultado deseado, tratando de acceder someValue plantea una AttributeError.

¿Cuál es la lógica detrás de este comportamiento? ¿Hay alguna forma de evitar esta limitación?

(estoy usando Zope 02/13/16, Python 2.7.3)

+0

¿Utiliza una clase base como la persistencia o la adquisición? –

+0

Tengo ObjectManager como una de las clases base (que hereda de Persistent) – Rastaf

+0

, así como Acquisition.Implicit. :-) –

Respuesta

6

El property decorator sólo funciona con nuevo estilo clases; es decir, clases que heredan de object. Adquisición (que le da acceso a la REQUEST objeto global a través de acceso atributo) por el contrario es mucho pitón 'vieja escuela' y los dos no trabajan bien juntos, como propertyignora envoltorios de adquisición, que son necesarios para adquirir el objeto REQUEST.

Zope tiene su propio property -como método que es anterior a clases de nuevo estilo y la property decorater, llamado ComputedAttribute, que en realidad es anterior a los property las clases de decorador y de nuevo estilo por muchos años. Un ComputedAttribute función -wrapped sabe cómo comportarse con un objeto -wrapped Acquisition, sin embargo.

Puede utilizar ComputedAttibute al igual que el property decorador:

from ComputedAttribute import ComputedAttribute 

class SomeClass(): 
    @ComputedAttribute 
    def someProperty(self): 
     return 'somevalue' 

La función ComputedAttribute envoltorio también se puede configurar con un nivel de envoltura, que es lo que necesitamos cuando se trata de envolturas de adquisición. No se puede utilizar el ComputedAttribute como decorador en ese caso:

class SomeClass(): 
    def someValue(self): 
     return self.REQUEST 
    someValue = ComputedAttribute(someValue, 1) 

Es bastante fácil de definir una nueva función para hacer la decoración para nosotros, sin embargo:

from ComputedAttribute import ComputedAttribute 

def computed_attribute_decorator(level=0): 
    def computed_attribute_wrapper(func): 
     return ComputedAttribute(func, level) 
    return computed_attribute_wrapper 

Pegue esto en un módulo de utilidad alguna parte , después de lo cual se puede luego usarlo como un decorador exigible a marcar algo como una propiedad de Adquisición-consciente:

class SomeClass(): 
    @computed_attribute_decorator(level=1) 
    def someValue(self): 
     return self.REQUEST 

Tenga en cuenta que a diferencia de property, ComputedAttribute solo se puede usar para getters; no hay soporte para setters o deleters.

+1

¡Muchas gracias! Estoy usando Zope desde hace un par de años y nunca tropecé con el método ComputedAttribute. – Rastaf

+0

Esto parece funcionar para mí en un caso (elemento de contenido Plone/Destreza), pero a los efectos de aclaración: ¿hay algún efecto secundario conocido de usar un decorador basado en atributos como este en las clases de nuevo estilo? ¿Qué clases base debe extender una clase para usar ComputedAttribute (por ejemplo, en una vista de navegador que participa en la adquisición)? – sdupton

+1

Solo puede usar ComputedAttribute en las clases derivadas de 'ExtensionClass' (que incluye las clases 'Acquisition.Explicit' y' Acquisition.Implicit'). Aparte de eso, no hay otros requisitos. –

3

Si desea ruta alrededor necesidad de adquisición y no se puede establecer explícitamente la petición de llamar código en el constructor de la clase, se utiliza zope.globalrequest. De lo contrario, es posible que desee considerar una vista de navegador (que siempre adapta de forma múltiple algún contexto y una solicitud).

+0

Gracias por indicarme zope.globalrequest. No tengo el paquete instalado, así que lo intentaré si alguna vez tengo que solucionar la adquisición. Por el momento estoy perfectamente satisfecho con la respuesta proporcionada por Martijn Pieters. ¿Qué quiere decir con "considerar una vista de navegador"? – Rastaf

Cuestiones relacionadas