4540l2.txt Listing 2. A Mix-in for Uniform Value Access class NamedValueError(KeyError): pass class _NoDefault: pass class NamedValueAccessible: def valueForKey(self, key, default=_NoDefault): ''' Suppose key is 'foo'. This method returns the value with the following precedence: 1. Methods before non-methods 2. Public attributes before private attributes More specifically, this method then returns one of the following: * self.foo() * self._foo() * self.foo * self._foo ...or default, if it was specified, otherwise raises an exception. ''' assert key klass = self.__class__ underKey = '_' + key attr = None method = getattr(klass, key, None) if not method: method = getattr(klass, underKey, None) if not method: attr = getattr(self, key, None) if not attr: attr = getattr(self, underKey, None) if not attr: if default!=_NoDefault: return default else: raise NamedValueError, key if method: return method(self) if attr: return attr