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
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?
(I’m using Zope 2.13.16, Python 2.7.3)
The
propertydecorator only works with new-style classes; that is to say, classes that inherit fromobject. Acquisition (which gives you access to the globalREQUESTobject via attribute access) on the other hand is very much ‘old-skool’ python and the two do not work well together, aspropertyignores acquisition wrappers, which are needed to acquire theREQUESTobject.Zope has it’s own
property-like method that pre-dates new-style classes and thepropertydecorater, calledComputedAttribute, which actually predates thepropertydecorator and new-style classes by many years. AComputedAttribute-wrapped function does know how to behave with anAcquisition-wrapped object, though.You can use
ComputedAttibutemuch like thepropertydecorator:The
ComputedAttributewrapper function also can be configured with a level of wrapping, which is what we need when dealing with Acquisition wrappers. You cannot use theComputedAttributeas a decorator in that case:It is easy enough to define a new function to do the decorating for us though:
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:
Note that unlike
property,ComputedAttributecan only be used for getters; there is no support for setters or deleters.