Guido van Rossum wrote: > On 4/4/06, Tim Hochberg <[EMAIL PROTECTED]> wrote: > [...] >> def __init__(self, name, doc=''): >> self.name = name >> self.registry = {} >> self.__doc__ = doc >> self.all_protocols.add(self) >> def __repr__(self): >> return "<protocol %r>" % self.name >> __str__ = __repr__ >> def __call__(self, *args): >> for key in self.keysof(*args): >> adapter = self.registry.get(key, None) >> if adapter is not None: >> return adapter(*args) >> raise ValueError('adapter not found') > > So __call__ is what used to be call adapt. Or, rather, where Alex used > to write adapt(x, P) and where I write P.adapt(x), you just write P(). > Clever.
I've used that in my example too (see http://mail.python.org/pipermail/python-3000/2006-April/000308.html) But might closes off one route we could take if we're adapting to something that must provide more than one function/method (i.e. an interface) and we'd like to have the interface and the adaption registry be identical. Suppose we're designing a new interface for sequence. A sequence must provide getitem() and len() methods. If the adapt(at)ion API only used register and adapt methods we could do something like this: class Interface(object): class __metaclass__(type): def __new__(mcl, name, bases, dict): # Give each class it's own registry dict["registry"] = {} return type.__new__(mcl, name, bases, dict) @classmethod def register(cls, adapter, T): cls.registry[T] = adapter @classmethod def adapt(cls, obj): for base in type(obj).__mro__: try: return cls.registry[base](obj) except KeyError: pass raise TypeError("can't adapt %r to %r" % (obj, cls)) class Sequence(Interface): def getitem(self, index): pass def len(self): pass class PythonSeqAsSequence(Sequence): 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.adapt([1,2,3]).len() 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. Bye, Walter Dörwald _______________________________________________ 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