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