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 So
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 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.
You can use ComputedAttibute
much like the property
decorator:
from ComputedAttribute import ComputedAttribute
class SomeClass():
@ComputedAttribute
def someProperty(self):
return 'somevalue'
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
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
Note that unlike property
, ComputedAttribute
can only be used for getters; there is no support for setters or deleters.