andrew cooke a écrit : > Hi, > > 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__ = {}
__names__ are reserved for the Python implementation itself. Use _names for 'protected' attributes. > 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) > > However, when I try to use this (in a test) with code like: > dao = ActiveDAO() > dao.add_field("name", "value", lambda _: None) > assertEqual(dao.name, "value") > > I get a failure because lookup of the attribute is returning > "<property object at 0x6b8910>". > > That is quite reasonable, but I was under the expression that some > magic was supposed to happen, as described in the document referenced > above! > > Please can someone explain why there is no magic? :o( Others already answered this. The canonical solution is to use a custom descriptor instead of a property: class Field(object): def __init__(self, name, onchange): self.name = name self.onchange = onchange def __get__(self, instance, cls): if instance is None: # called on the class return self # called on instance return instance._values[self.name] def __set__(self, instance, value): instance._values[name] = self.onchange(value) class ActiveDAO(object): def __init__(self): self._values = [] class Person(ActiveDAO): name = Field('firstname', lambda v: v.strip().capitalize()) age = Field('age', lambda v : int(v)) Now you may want to search here or in the cookbook to learn how to: - dynamically create new classes - avoid having to repeat the name of the field (usually done using a metaclass and a two-stages initialisation of Field objects) HTH -- http://mail.python.org/mailman/listinfo/python-list