Walter Dörwald wrote: > But if adapting is done via __call__() we have a problem: Sequence > already provides a __call__, the constructor. Of course if this worked > > print Sequence([1,2,3]).len() > > would look much better than > > print Sequence.adapt([1,2,3]).len() > > but I'm not sure if it's possible to work around the constructor/adapt > clash.
You can redefine __call__ in the metaclass to fix it: Py> class ClassCall: ... class __metaclass__(type): ... def __call__(cls): ... print "Calling", cls ... Py> ClassCall() Calling <class '__main__.ClassCall'> 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() -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com