property and virtuality

Michele Simionato michele.simionato at gmail.com
Fri Apr 1 23:57:54 EST 2005


Diez B. Roggisch:

> On second thoughts, a metaclass _might_ help here - but it would be
rather
> elaborate: look in the baseclasses for properties that have getters
and
> setters of the same name as some methods in the current class, and
replace
> them, or  create a new property with them (I'm not sure if
descriptors
> allow changing their get/set/del methods). I'm not 100% sure if and
how
> good that works (a quick hack would be easy, but to ship around the
cliffs
> of multiple inheritance requires more careful navigation I fear...)

Maybe you are worrying to much. Here is a quick metaclass solution
which
magically generates properties from methods which name starts with
"get"
or "set":

class MagicProperties(type):
    def __init__(cls, name, bases, dic):
        prop_names = set(name[3:] for name in dic
                         if name.startswith("get")
                         or name.startswith("set"))
        for name in prop_names:
            getter = getattr(cls, "get" + name, None)
            setter = getattr(cls, "set" + name, None)
            setattr(cls, name, property(getter, setter))

class Base(object):
    __metaclass__ = MagicProperties
    def getx(self):
        return self._x
    def setx(self, value):
        self._x = value

class Child(Base):
    def getx(self):
        print "getting x"
        return super(Child, self).getx()
    def setx(self, value):
        print "setting x"
        super(Child, self).setx(value)

c = Child()
c.x = 1
print c.x

This should work well for multiple inheritance too (modulo metaclass
conflicts).

I must say, however, that I never use this idiom (i.e. polluting my
classes
with tons of getters and setters and making properties from them).
I typically use a property factory function, or a custom descriptor.


                Michele Simionato




More information about the Python-list mailing list