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