Overridable Properties

From IronPython Cookbook

Revision as of 17:12, 19 June 2007 by Dodiggitydag (Talk | contribs)

Creating properties in IronPython is a little more complicated than using your favorite .NET strongly-typed language. IronPython uses a property "method" to create a property accessor.

The full signature of the "method" is property(fget=None, fset=None, fdel=None, doc=None). The fget, fset and fdel arguments are the methods called when the attribute is get, set or deleted. If any of these three is unspecified or None, the corresponding operation will raise an AttributeError exception. The fourth argument is the doc string for the attribute.[1]

Not Overridable Properties

Standard IronPython/Python implements properties in the following way:

class C(object):
	def __init__(self):
		self.__x = 0

	def getx(self):
		return self.__x

	def setx(self, x):
		if x < 0: x = 0
		self.__x = x

	x = property(getx, setx)

See the Python.org reference Unifying types and classes in Python for more information.

Overridable Properties

Using this convension, it is possible for derived classes to override property implementation. When decaring the property it must use lambda functions to resolve the method to call at run time, instead of when the base class is initialized.

class Base(object):
	def __init__(self):
		self.foo = None

	def getFoo(self):
		return self.__foo

	def setFoo(self, val):
		self.__foo = val

	# For properties which can be overriden in a derived class:
 	foo = property(fget=lambda self: self.getFoo(),
			fset=lambda self, v: self.setFoo(v))

class Derived(Base):
	def getFoo(self):
		"""Same as in Base, but default to 0 instead of None."""
		result = super(Derived, self).getFoo()
		if result != None:
			return result
			return 0

if __name__ == "__main__":
	# Test the above class
	t1 = Base()
	assert t1.foo == None
	t1.foo = "Something"
	assert t1.foo == "Something"

	t2 = Derived()
	assert t2.foo == 0
	t2.foo = "bar"
	assert t2.foo == "bar"

Thanks to Fun with Python Properties for the great idea!