2012-09-22 64 views
6

我试图在一个类中使用属​​性装饰器。尽管它本身运行良好,但我无法使用任何必须访问REQUEST的代码。Zope:无法访问属性上的请求装饰器

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 

虽然叫get_someValue得到我想要的结果,试图访问someValue引发AttributeError

这种行为背后的逻辑是什么?有没有办法解决这个限制?

(我使用Zope的2.13.16,Python的2.7.3)

+0

您是否使用诸如Persistence或Acquisition之类的基类? –

+0

我有ObjectManager作为其中一个基类(从Persistent继承) – Rastaf

+0

以及Acquisition.Implicit。 :-) –

回答

6

property decorator只适用于新型班;也就是说,从object继承的类。获取(通过属性访问可以访问全局REQUEST对象)是非常多的“old-skool”python,两者不能很好地协同工作,因为property忽略了获取包装器,这是需要获取REQUEST对象。

的Zope有它自己的property式的方法,早新型类和property decorater,叫ComputedAttribute,这实际上通过多年早于property装饰和新的样式类。但是,ComputedAttribute包装的函数确实知道如何处理Acquisition包装的对象。

您可以使用ComputedAttibute很像property装饰:

from ComputedAttribute import ComputedAttribute 

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

ComputedAttribute包装函数也可以用包装的水平,这是我们需要采集的包装打交道时进行配置。实用模块中

from ComputedAttribute import ComputedAttribute 

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

棒这个地方:你不能使用ComputedAttribute作为装饰在这种情况下:

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

这是很容易定义一个新的功能做装饰为我们虽然,之后,你就可以使用它作为一个可调用的装饰,以纪念的东西作为采集感知特性:

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

注意,不像propertyComputedAttribute只能用于吸气剂;不支持setter或deleters。

+1

非常感谢!我已经使用Zope几年了,从未偶然发现过ComputedAttribute方法。 – Rastaf

+0

这似乎适用于我的情况(Plone /敏捷内容项目),但出于澄清的目的:是否有任何已知的使用基于ComputedAttribute的装饰器在新样式类上的副作用?为了使用ComputedAttribute(例如,在参与收购的浏览器视图中),类必须扩展到哪些基类? – sdupton

+1

您只能对从'ExtensionClass'派生的类(包括'Acquisition.Explicit'和'Acquisition.Implicit'类)使用ComputedAttribute。除此之外,没有其他要求。 –

3

如果您想围绕需要获取并且无法在您的类的构造函数中显式设置调用代码的请求,请使用zope.globalrequest。否则,您可能需要考虑一个浏览器视图(它总是对某些上下文和请求进行多重调整)。

+0

感谢您指点我zope.globalrequest。我没有安装这个软件包,所以如果我需要绕过收购,我会试一试。目前,我非常满意Martijn Pieters提供的答案。 “考虑浏览器视图”是什么意思? – Rastaf