Read Only attributes, auto properties and getters and setters

TechieInsights GDoermann at gmail.com
Thu Feb 12 12:27:07 EST 2009


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.



More information about the Python-list mailing list