6

我正在尝试在类中使用属​​性装饰器。虽然它本身运行良好,但我不能使用任何必须访问REQUEST.

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)

4

2 回答 2

7

property装饰器只适用于新式类;也就是说,继承自object. REQUEST另一方面,获取(它使您可以通过属性访问访问全局对象)是非常“老派”的python,两者不能很好地协同工作,因为property 忽略了获取对象所需的获取包装器REQUEST

Zope 有它自己的property类似方法,它早于新式类和property装饰器,称为ComputedAttribute,它实际上早于property装饰器和新式类很多年。但是,一个ComputedAttribute-wrapped 函数确实知道如何处理一个Acquisition-wrapped 对象。

你可以ComputedAttibuteproperty装饰器一样使用:

from ComputedAttribute import ComputedAttribute

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

包装函数也可以配置一个ComputedAttribute包装级别,这是我们在处理 Acquisition 包装时需要的。在这种情况下,您不能将ComputedAttribute用作装饰器:

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

定义一个新函数来为我们做装饰很容易:

from ComputedAttribute import ComputedAttribute

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

将其粘贴在某个实用程序模块中,然后您可以将其用作可调用装饰器以将某些内容标记为 Acquisition-aware 属性:

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

注意,不像property,ComputedAttribute只能用于 getter;不支持设置器或删除器。

于 2012-09-22T15:52:35.540 回答
3

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

于 2012-09-22T21:10:12.117 回答