Read Only attributes, auto properties and getters and setters

josh logan dear.jay.logan at gmail.com
Thu Feb 12 13:11:50 EST 2009


On Feb 12, 12:27 pm, TechieInsights <GDoerm... at gmail.com> wrote:
> 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.

I think I'll stick with the built-in, Thanks :)



More information about the Python-list mailing list