[Python 2.2] Properties, a simple module for playing

Mike C. Fletcher mcfletch at geocities.com
Thu Jan 31 00:40:11 CET 2002

	Property class hierarchies derived from the built-in property class make 
it possible to re-use large quantities of property-relevant code.  I've 
hacked together a fairly generic set of property classes and supporting 
objects into a module with which people can play.


Brief Introduction:
	Properties become very useful when you're creating frameworks that are 
using introspection at run-time to create GUI or similar interfaces. 
It's possible to use the built-in Python 2.2 properties as-is, but you 
then need to write (up to 3) methods for each property, as that class 
assumes you're using properties to spell "method-mediated attribute access".
	In my code, however, what I normally need is a class hiearchy of property 
types, where each property of the given type is basically the same, and 
objects are just collections of properties with a very minimal bit of 
custom processing.  In this environment, each property needs certain 
support mechanisms (coercian, type-checking).
	In response to this need, I created a small module which provides a 
generic property object from which to derive the various property types 
I need.  What this module does is allow you to specify a class like so:

 >>> class X(object):
... 	b = basicproperty.IntegerProperty( 'b',"A demonstration integer 
property", )
... 	c = basicproperty.StringProperty( 'c', "A string property" )
... 	d = basicproperty.IntegerProperty( 'd',"A demonstration integer 
property constrained to range 0 <= x <= 10", bounds = 
[basicproperty.RangeBoundary(0,10),] )
 >>> a = X()
 >>> a.b = 3
 >>> a.b
 >>> a.c = 4
 >>> a.c
 >>> a.d = 20
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "p:\basicproperty.py", line 21, in setValue
     self.check ( client, value )
   File "p:\basicproperty.py", line 36, in check
     for boundary in self.bounds:
   File "p:\basicproperty.py", line 59, in __call__
     raise ValueError ("""Property value was too low, minimum is %s, 
value was %s"""%(self.minimum, value))
ValueError: Property value was too high, maximum is 10, value was 20
 >>> a.d = 10
 >>> a.d = '10'
 >>> a.d

In this case, my particular IntegerProperty class provides coercian, 
type checking, optional bounds checking, and storage/retrieval in the 
object's __dict__.  The current mechanism allows for specifying bounds 
such as "instance of a class" (which is how IntProperty/StringProperty 
define themselves), so you could as easily create a property which must 
be an instance of X:

	e = basicproperty.BasicProperty( 'e', 'X property', bounds = 

What's missing (it was pointed out the first time I posted about 
properties) is compound data types (lists, dictionaries) which would 
support both assigning to the list and doing classic slicing.  That 
shouldn't be particularly tricky, you could create a derivative of 
list/dict that has assignment coercian/constraints and use that as the 
value stored in the instance by the property.  I don't have time to get 
that done now, so I'll follow the "release early and often" creed and 
let others play with the basic properties now.


Have fun all,
   Mike C. Fletcher

More information about the Python-list mailing list