Python Chains

dictchain objects are dictionary subtypes which delegate requests for key and attributes requests.
You can view the download list here

dictchain

A dictchain is a dictionary which, when asked for a key that it doesn't contain, will examine other dictionaries in an attempt to determine the correct value for a key. The constructor for a dictchain accepts zero or more Python objects and any number of keyword arguments (these are assigned to the dictchain just like dict's constructor). The positional arguments are then used to form the __chain__ member of the dictchain. This member may be read or altered during the life of the dictchain and must contain a sequence of dictionary objects (or None for No-op). When a request is made of a dictchain that it does not have a value for the links in the __chain__ are examined one at a time until one of the links produces a value (including None) or the link raises a KeyError. On each given non-None link, which must be a dictionary subclass (which includes other dictchains), that link is interrogated for the key requested. If it does not raise a KeyError then the returned object is returned to the requester of the dictchain.

dictchains also have some interesting methods/attributes:

dictchains also translate attribute access to key requests. So, any attribute request turns into a __getitem__, thus allowing chaining to occur on attributes too. Now with Python 2.4, an object's __dict__ can also be assigned a dictchain object for even more fun!

Examples

Simple chaining

In this example, we inherit the values from another dictionary:
from pychains import dictchain

d={'x':'hello'}
dc=dictchain(d)
print dc['x']			# Prints 'hello'
We can override the value of x in the dictchain as follows:
dc['x']='world'
print dc['x']			# Now prints 'world'
We can also chain a dictchain:
dc2=dictchain(dc)
print dc2['x']			# Still prints 'world'
We can also use it to generate default values. Note that you MUST provide a constructor to set __chain__ -- it cannot be set in the class with methods:
class mydict(dictchain):
	def __makeitem__(self,name):
		print 'Generating '+name
		self[name]=name+'!'     # Cache the result
		return self[name]
md=mydict()
print md['hello']		# Prints "Generating hello" and "hello!"
print md['hello']		# Only prints "hello!" this time.
Note that the above is very different from dict's setdefault() in that the default value is generated only if it doesn't exist.

Contacting...

This software is maintained by Rich Harkins. It is being distributed under the GPL. Please contact me with bugs, suggestions, comments, etc. via sourceforge. If you wish to contact me about something not covered under sourceforge, feel free to email me
Graciously hosted by: SourceForge.net Logo