[Python-3000] Adaptation vs. Generic Functions
Tim Hochberg
tim.hochberg at cox.net
Wed Apr 5 22:44:22 CEST 2006
Walter Dörwald wrote:
> Guido van Rossum wrote:
>
>> Fascinating ideas in this thread!
>>
>> I spent some time blogging about this on artima:
>> http://www.artima.com/weblogs/viewpost.jsp?thread=155123
>>
>> I have to write my slides for a talk about Py3K later today, but I'll
>> be back. In the mean time I've rejected PEPs 245 and 246 in
>> expectation of something better that's imminent!
>
>
> What's still missing IMHO is a way for an adapter to defer to the next
> adapter in the chain, i.e. something like:
>
> class Protocol(object):
> def register(self, ...):
> ...
>
> def __call__(self, ...):
> ...
>
> def default(self, *args, **kwargs):
> raise TypeError
>
> def candidates(self, *args, **kwargs):
> return type(args[0]).__mro__
>
> def super(self, *args, **kwargs):
> search = iter(self.candidates(*args, **kwargs))
> for key in search:
> if key in self.registry:
> break
> try:
> return search.next()(*args, **kwargs)
> except StopIteration:
> return self.default(*args, **kwargs)
>
>
> With this an adapter could use the super() method to call the next
> adapter in the chain:
>
> p = Protocol()
>
> @p.register(Foo)
> def p_foo(foo):
> p.super(foo)
The concept seems good, but I find the implementation baffling, OK, I
finally figured it out. It only seems to work once though -- you can't
chain super calls. Why not simply raise a DeferToNextAdapter exception?
That seems much simpler and it chains correctly.
class DeferToNextAdapter(Exception):
pass
class Protocol(object):
#....
def __call__(self, *args):
"""Adapt supplied arguments to this protocol"""
for key in self.signatures(args):
try:
try:
adapter = self.registry[key]
except
pass
else:
return adapter(*args)
except DeferToNextAdapter:
pass
return self.default_adapter(*args)
p = Protocol()
@p.register(Foo)
def p_foo(foo):
raise DeferToNextAdapter
=========================================
FWIW, I'm also not very enthusiastic about the inner try/except block
that showed up at some point. The normal case is to fail here, so it
seem like this results in unnecessary overhead. That's a minor issue though.
Regards,
-tim
More information about the Python-3000
mailing list