Declarative properties

George Sakkis george.sakkis at gmail.com
Fri Oct 12 03:01:41 CEST 2007


On Oct 11, 7:04 pm, George Sakkis <george.sak... at gmail.com> wrote:

> You could take it even further by removing the need to repeat the
> attribute's name twice. Currently this can done only through
> metaclasses but in the future a class decorator would be even
> better:

Replying to myself here, but actually metaclasses is not the only way;
another solution involves a descriptor class:


class Property(object):

    # cache the mapping of types to 'private' attribute names
    _type2attrname = {}

    def __init__(self, format='_%s'):
        self._format = format

    def __get__(self, obj, type=None):
        try: name = self._type2attrname[type(obj)]
        except KeyError:
            self._type2attrname[type(obj)] = name =
self._get_propname(obj)
        return getattr(obj, name)

    def __set__(self, obj, value):
        try: name = self._type2attrname[type(obj)]
        except KeyError:
            self._type2attrname[type(obj)] = name =
self._get_propname(obj)
        setattr(obj, name, value)

    def _get_propname(self, obj):
        for cls in type(obj).mro():
            for name,value in cls.__dict__.iteritems():
                if value is self:
                    return self._format % name
        assert False  # unreachable


#---- example ------------------------------------

class Person(object):
    name = Property()

    def __init__(self, name):
        self.name = name

p = Person('John')
q = Person('Mike')
print p.name, q.name
print p.__dict__


George




More information about the Python-list mailing list