andrew cooke <[EMAIL PROTECTED]> writes: > This is my first attempt at new classes and dynamic python, so I am > probably doing something very stupid... After reading the how-to for > descriptors at http://users.rcn.com/python/download/Descriptor.htm I > decided I would make an object that returns attributes on read, but on > setting calls an arbitrary function. > > My code looks like: > class ActiveDAO(object): > def __init__(self): > self.__values__ = {} > def add_field(self, name, value, on_change): > self.__values__[name] = value > def get(self): return self.__values__[name] > def set(self, new_value): self.__values__[name] = > on_change(new_value) > def delete(self): raise AttributeError > self.__dict__[name] = property(get, set, delete)
As others explained, descriptors are called for descriptors found in class attributes, not in ones in instance attributes. Calling them for the latter would be dangerous because it might accidentally invoke magic whenever you store the "wrong" kind of object in an instance attribute. Also, in many cases (slots), instance property access is *implemented* using class property descriptors, so calling descriptors on objects retrieved from the instance would mean that the descriptor would have to be invoked twice. However, if you know what you're doing, you can simply customize your class's __getattribute__ to do what *you* want for your objects. For example: def __getattribute__(self, name): dict = object.__getattribute__(self, '__dict__') # self.__dict__ would infloop if name in dict: o = dict[name] # call the descriptor even if found in an object in __dict__ if hasattr(o, '__get__'): return o.__get__(self, type(self)) return o return object.__getattribute__(self, name) With that addition: >>> dao = ActiveDAO() >>> dao.add_field('name', 'value', lambda _: None) >>> dao.name 'value' >>> dao.__dict__['name'] <property object at 0xb7d53284> -- http://mail.python.org/mailman/listinfo/python-list