Ok... for some closure I have written a class to automate the
process.  It takes getters and setters and deleters and then sets the
property automatically.  Sweet!


class AutoProperty(type):
        def __new__(cls, name, bases, methoddict):
                processed = []
                getter = 'get_'
                setter = 'set_'
                deleter = 'del_'

                starters = {getter:PropertyAttr(getter, PropertyAttr.FGET),
                                        setter:PropertyAttr(setter, 
PropertyAttr.FSET),
                                        deleter:PropertyAttr(deleter, 
PropertyAttr.FDEL)
                                        }
                for key, value in methoddict.items():
                        var = None
                        for start in starters.keys():
                                if key.startswith(start):
                                        var = key[len(start):]
                                        break
                        if var is None or var in processed:
                                continue
                        property_values = []

                        for start in starters.keys():
                                if '%s%s' %(start, var) in methoddict.keys():
                                        
property_values.append(starters[start].tostring(var))
                                else:
                                        
property_values.append(starters[start].tostring(None))
                        property_map = 'methoddict["%s"] = property(%s)' %(var, 
','.join
(property_values))
                        exec(property_map)
                return type.__new__(cls, name, bases, methoddict)

class PropertyAttr(object):
        FGET = 'fget'
        FSET = 'fset'
        FDEL = 'fdel'
        def __init__(self, start, type = FGET):
                self.start = start
                self.type = type

        def tostring(self, var):
                if self.type == self.FSET:
                        vars = ['v']
                else:
                        vars = []
                fullvar = ['self'] + vars
                if var is None:
                        return '%s=None' %(self.type)
                return '%s=lambda %s: self.%s%s(%s)' %(self.type, 
','.join(fullvar),
self.start, var, ','.join(vars))

class ReadOnly(object):
        __metaclass__ = AutoProperty


class MyClass(ReadOnly):
        def __init__(self, x, y):
                self.__x = x
                self.__y = y

        def get_x(self):
                return self.__x

        def set_x(self, x):
                self.__x = x

        def get_y(self):
                return self.__y

mc = MyClass(10, 100)
print mc.x, mc.y
mc.x = 10
print mc.x
try:
        mc.y = 100
except AttributeError:
        print 'Yea it worked!'

try:
        del mc.y
except AttributeError:
        print "It's read only!"

And the output:
10 100
10
Yea it worked!
It's read only!


Now to work on descriptors doing it for you.
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to