[Python-3000] Adaption & generic functions [was Generic functions]

Walter Dörwald walter at livinglogic.de
Wed Apr 5 13:52:47 CEST 2006


Nick Coghlan wrote:

> [...]
> So your example would become:
> 
> class MetaInterface(type):
>      def __new__(mcl, name, bases, dict):
>          # Give each class it's own registry
>          cls = type.__new__(mcl, name, bases, dict)
>          cls.registry = {}
>          return cls
> 
>      def register(cls, adapter, T):
>          cls.registry[T] = adapter
> 
>      def register_for(cls, T):
>          # Registration decorator
>          def register_func(adapter):
>              cls.register(adapter, T)
>          return register_func
> 
>      def __call__(cls, obj):
>          # Cannot construct interface instances
>          # Instead, calling the class triggers adaptation
>          for base in type(obj).__mro__:
>              try:
>                  adapter = cls.registry[base]
>              except KeyError:
>                  pass
>              if adapter is None:
>                  return obj
>              return adapter(obj)
>          raise TypeError("can't adapt %r to %r" % (obj, cls))
> 
> class Interface(object):
>      __metaclass__ = MetaInterface
> 
> class Sequence(Interface):
>      def getitem(self, index): pass
>      def len(self): pass
> 
> 
> class PythonSeqAsSequence(object): # Adapter is a normal class!
>      def __init__(self, obj):
>         self.obj = obj
> 
>      def getitem(self, index):
>         return self.obj[i]
> 
>      def len(self):
>         return len(self.obj)
> 
> Sequence.register(PythonSeqAsSequence, list)
> 
> print Sequence([1,2,3]).len()
> 
> # Or using the function decorator version
> @Sequence.register_for(tuple)
> def tuple_as_seq(obj):
>      class AdaptedTuple(object):
>          def getitem(self, index):
>              return obj[i]
>          def len(self):
>              return len(obj)
>      return AdaptedTuple()

Of course it would be better, if we had class decorators:

@Sequence.register_for(tuple)
class AdaptedTuple(object):
   def __init__(self, obj): self.obj = obj
   def getitem(self, index): return self.obj[i]
   def len(self): return len(self.obj)

But this doesn't look too bad. Not being able to instantiate an
interface actually makes sense. What looks debatable to me is that it
adapter doesn't subclass the interface (it would then inherit some
default implementations of methods).

Servus,
   Walter



More information about the Python-3000 mailing list