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