2012-09-22 6 views
6

Ich versuche, den Property Decorator in einer Klasse zu verwenden. Während es per se gut funktioniert, kann ich keinen Code verwenden, der auf die REQUEST zugreifen muss.Zope: kann nicht auf REQUEST unter Property Decorator zugreifen

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 

Obwohl get_someValue Aufruf wird mir das gewünschte Ergebnis, versuchen, ein AttributeError zuzugreifen someValue wirft.

Was ist die Logik hinter diesem Verhalten? Gibt es eine Möglichkeit, diese Einschränkung zu umgehen?

(Ich verwende Zope 2.13.16, Python 2.7.3)

+0

Verwenden Sie eine Basisklasse wie Persistence oder Acquisition? –

+0

Ich habe ObjectManager als eine der Basisklassen (die von Persistent erbt) – Rastaf

+0

sowie Acquisition.Implicit. :-) –

Antwort

6

Die property decorator funktioniert nur mit neuen Stil Klassen; das heißt, Klassen, die von object erben. Acquisition (das gibt Ihnen Zugriff auf die globale REQUEST Objekt über Attributzugriff) auf der anderen Seite ist sehr viel "old-skool" Python und die beiden nicht gut zusammen, wie propertyignoriert Erwerb Wrapper, die benötigt werden, um zu erwerben das Objekt REQUEST.

Zope hat eine eigene property -ähnlichen Methode ist, die neue Stil-Klassen und die property decorater früher, genannt ComputedAttribute, die eigentlich schon vor die property Dekorateur und neuen Stil Klassen von vielen Jahren. Eine ComputedAttribute -wrapped-Funktion weiß jedoch, wie sie sich mit einem Acquisition-Wrapped-Objekt verhält.

können Sie ComputedAttibute verwenden viel wie der property Dekorateur:

from ComputedAttribute import ComputedAttribute 

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

Die ComputedAttribute Wrapper-Funktion kann auch mit einem Pegel von Wickel konfiguriert werden, das, was wir brauchen, ist, wenn sie mit Acquisition-Wrapper zu tun. Sie können nicht die ComputedAttribute als Dekorateur in diesem Fall verwenden:

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

Es ist leicht genug, um eine neue Funktion zu definieren, wenn für uns die Dekoration zu tun:

from ComputedAttribute import ComputedAttribute 

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

Halten Sie diese in einem Versorgungsmodul irgendwo , nach dem Sie dann als aufrufbare Dekorateur verwenden sie etwas als Acquisition-aware Eigenschaft zu markieren:

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

Beachten Sie, dass im Gegensatz zu property, ComputedAttribute kann nur für Getter verwendet werden; Es gibt keine Unterstützung für Setter oder Deleter.

+1

Vielen Dank! Ich benutze Zope schon seit ein paar Jahren und stolperte nie über die Methode ComputedAttribute. – Rastaf

+0

Dies scheint für mich in einem Fall zu funktionieren (Plone/Dexterity-Inhaltselement), aber zur Verdeutlichung: Gibt es bekannte Nebenwirkungen bei der Verwendung eines ComputedAttribute-basierten Dekorators wie bei neuen Stilklassen? Welche Basisklassen muss eine Klasse erweitern, um ComputedAttribute zu verwenden (z. B. in einer Browseransicht, die an der Erfassung beteiligt ist)? – sdupton

+1

Sie können ComputedAttribute nur für Klassen verwenden, die von'ExtensionClass' abgeleitet sind (einschließlich der Klassen 'Acquisition.Explicit' und' Acquisition.Implicit'). Ansonsten gibt es keine anderen Anforderungen. –

3

Wenn Sie eine Route umleiten möchten, die eine Erfassung erfordert, und die Anforderung nicht explizit vom aufrufenden Code im Konstruktor Ihrer Klasse aus festlegen können, verwenden Sie zope.globalrequest. Andernfalls sollten Sie eine Browseransicht in Betracht ziehen (die einen Kontext und eine Anfrage immer mehrfach anpasst).

+0

Danke, dass Sie mich auf zope.globalrequest verwiesen haben. Ich habe das Paket nicht installiert, also werde ich es versuchen, wenn ich mich jemals um die Anschaffung kümmern muss. Im Moment bin ich vollkommen zufrieden mit der Antwort von Martijn Pieters. Was meinen Sie mit "Betrachten einer Browser-Ansicht"? – Rastaf