I wrote up a simple example. You can view the complete file on Zenoss Trac. Running the file runs a unit test.
An 'x' attribute is declared on MyClass. The value of 'x' will be accessed as a string, but it is declared to be a MyDescriptor.
class MyClass(object):
pass
for id in ['x']:
setattr(MyClass, id, MyDescriptor(id))
The MyDescriptor instance prepends 'bar_' to the value that is set on the 'x' attribute of a MyClass instance. This value is stored in a dictionary named '_values' on the MyClass instance.
def __set__(self, instance, value):
if not hasattr(instance, '_values'): instance._values = {}
instance._values[self.id] = 'bar_' + value
When the 'x' attribute is fetched from a MyClass Instance, the MyDescriptor instance prepends 'foo_' to the value it finds in '_values'.
def __get__(self, instance, owner):
if instance is None: return self
else: return 'foo_' + instance._values[self.id]
More information on descriptors is in the Python docs.