问题描述
我正在尝试在类中使用属性装饰器.虽然它本身运行良好,但我不能使用任何必须访问 REQUEST
的代码.
I'm trying to use the property decorator in a Class. While it works well per se, I can't use any code that has to access the 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
.
Although calling get_someValue
gets me the desired result, trying to access someValue
raises an AttributeError
.
这种行为背后的逻辑是什么?有没有办法绕过这个限制?
What's the logic behind this behaviour? Is there a way to get around this limitation?
(我使用的是 Zope 2.13.16,Python 2.7.3)
(I'm using Zope 2.13.16, Python 2.7.3)
推荐答案
property
装饰器仅适用于新风格类;也就是说,继承自object
的类.另一方面,获取(它使您可以通过属性访问访问全局 REQUEST
对象)是非常老式"的 python,并且两者不能很好地协同工作,因为 property
忽略获取包装器,这是获取REQUEST
对象所必需的.
The property
decorator only works with new-style classes; that is to say, classes that inherit from object
. Acquisition (which gives you access to the global REQUEST
object via attribute access) on the other hand is very much 'old-skool' python and the two do not work well together, as property
ignores acquisition wrappers, which are needed to acquire the REQUEST
object.
Zope 有它自己的类似 property
的方法,它早于新样式类和 property
装饰器,称为 ComputedAttribute
,它实际上比 property
装饰器和新式类早了很多年.不过,ComputedAttribute
包装的函数确实知道如何处理 Acquisition
包装的对象.
Zope has it's own property
-like method that pre-dates new-style classes and the property
decorater, called ComputedAttribute
, which actually predates the property
decorator and new-style classes by many years. A ComputedAttribute
-wrapped function does know how to behave with an Acquisition
-wrapped object, though.
您可以像使用 property
装饰器一样使用 ComputedAttibute
:
You can use ComputedAttibute
much like the property
decorator:
from ComputedAttribute import ComputedAttribute
class SomeClass():
@ComputedAttribute
def someProperty(self):
return 'somevalue'
ComputedAttribute
包装器函数也可以配置一个包装级别,这是我们在处理 Acquisition 包装器时所需要的.在这种情况下,您不能使用 ComputedAttribute
作为装饰器:
The ComputedAttribute
wrapper function also can be configured with a level of wrapping, which is what we need when dealing with Acquisition wrappers. You cannot use the ComputedAttribute
as a decorator in that case:
class SomeClass():
def someValue(self):
return self.REQUEST
someValue = ComputedAttribute(someValue, 1)
定义一个新函数来为我们进行装饰很容易:
It is easy enough to define a new function to do the decorating for us though:
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 属性:
Stick this in a utility module somewhere, after which you can then use it as a callable decorator to mark something as an Acquisition-aware property:
class SomeClass():
@computed_attribute_decorator(level=1)
def someValue(self):
return self.REQUEST
注意与property
不同,ComputedAttribute
只能用于getter;不支持设置器或删除器.
Note that unlike property
, ComputedAttribute
can only be used for getters; there is no support for setters or deleters.
这篇关于Zope:无法访问属性装饰器下的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!