[Python-3000] Adaptation [was:Re: Iterators for dict keys, values, and items == annoying :)]

Tim Hochberg tim.hochberg at ieee.org
Sat Apr 1 20:52:14 CEST 2006


Benji York wrote:
> Aahz wrote:
> 
>>On Fri, Mar 31, 2006, Alex Martelli wrote:
>>
>>
>>>Once in a while, I'm moved to sing this refrain again, but thanks to  
>>>the ensuing discussion I'm soon reminded that there are many more  
>>>gratifying activities I could pursue instead -- repeated beating of  
>>>my forehead against suitable brick walls spring to mind as being both  
>>>more productive and more fun, for example.
>>
>>
>>That's because you're a masochist.  ;-)
>>
>>Seriously, I can almost see why you think adaptation is a huge gain, but
>>every time I start looking closer, I get bogged down in trying to
>>understand adaptation registration.  Do you have a simple way of
>>explaining how that works *well* and *simply*?  Because unless one can
>>handle registration cleanly, I don't understand how adaptation can be
>>generally useful for Python.  Conversely, if adaptation registration is
>>*NOT* required, please explain that in simple terms.
> 
> 
> In Zope 3 adapters are normally registered via a one line ZCML 
> directive, but that's more for configuration management than anything 
> else; it makes it easier to swap adapters in and out.  You can also use 
> Python to do the same thing:
> 
> from zope import component
> component.provideAdapter(MyAdapter)
> 
> MyAdapter can be any callable that takes one or more objects (the things 
> being adapted) and provides a single interface.  The class would look 
> like this:
> 
> class MyAdapter:
>      component.adapts(ISomething)
>      interface.implements(ISomethignElse)
> 
>      def __init__(self, something):
>          ...
> 
> So in this case the "provideAdapter" queries the adapter to find out 
> what is being adapted to and from.  You can also provide those to the 
> provideAdapter call if MyAdapter implements more than one interface or 
> you need to for some other reason.

Bah! This is why adapters never get anywhere. My eyes glazed over 10 
lines ago. At their core, adapters seem like a simple enough concept, 
but whenever anyone starts talking about them we get what seems like 
overengineered examples that make my brain lock up. Someone who knows 
something about adapters needs to go off and come up with the worlds 
simplest, most light weight, dumb as a post, adapter proposal. It may 
not be what you eventually want, but until people can grok the idea in a 
few simple lines of code it's not going to get that groundswell of 
support that Alex keeps looking for.

Couldn't an adapter protocol be as simple as a module with a dictionary 
in it and two methods?

# adapters.py
registry = {}
def register(adapter, resultdescr, *targetdescrs):
     for x in targetdescrs:
         registry[(resultdescr, x)] = adapter
def find(resultdescr, targetdescr):
     return registry[(resultdescr, target)]

The convention being that adapter(target) = result, where target and 
result satisfy targetdescr and resultdescr in some sense. What these 
descriptions are doesn't matter much as long as they're hashable and the 
users can come to some agreement. Here's a trivial example:

adapters.register(list, 'sequence', generatortype, dictkeyitertype,...)
#...
def f(obj):
     seq = adapters.find('sequence', type(obj))(obj)
     # do stuff with seq


I'm assuming that sticking the above six lines in a file somewhere 
wouldn't be sufficient for some reason, but if not, why not? And what's 
the simplest possible proposal that would work?


Regards,

-tim

> 
> For adapters that are just functions, decorators can be used to indicate 
> the "to" and "from" interfaces (following the "index" example from earlier):
> 
> @component.adapter(IMpz)
> @interface.implementer(IIndex)
> def index(mpz):
>      return long(mpz)
> 
> The zope.component README goes into more detail (especially the 
> "Adapters" section):
> http://svn.zope.org/*checkout*/Zope3/trunk/src/zope/component/README.txt?rev=39671
> --
>



More information about the Python-3000 mailing list