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

Ian Bicking ianb at colorstudy.com
Sat Apr 1 00:36:44 CEST 2006


Benji York wrote:
> Alex Martelli wrote:
> 
>>If the framework consuming X requested adaptation-to-X on all objects
>>it's passed,
> 
> 
> That's not generally the way Zope 3 does it (and doesn't sound like a 
> good idea to me).
> 
> There are three ways (as I see it) adaptation is used in Z3.  First, the 
> traditional idea of an "adapter", in which something has the right 
> state, but the wrong interface.  That form of adaptation is used when 
> plugging different components together (whether they are Z3 or come from 
> other projects).  In that way of using adaptation a 
> function/method/whatever wants things that act in a particular way (duck 
> typing).  If I, as the user of the interface, have something I want to 
> pass in that doesn't match I it to the appropriate interface the burden 
> is on me to create something that matches expectations.  People do that 
> all the time today without an interface/adaption framework, they just 
> write code that takes one thing and builds another.
> 
> Greg Ewing wrote:
> 
>>This is the part that bothers me, I think. It
>>seems like all these adaptation requests would
>>be a huge burden on the framework developer.
> 
> 
> Not in the above scenario, when using adapters like that the burden is 
> on the user.  That might sound like a bad thing, but if they're 
> exclusively using your library, they already have objects of the 
> necessary type, if not they have an adaptation framework to help them do 
> something they'd have to do anyway.
> 
> The second way adaptation is used is as a general lookup facility.  Say 
> that I have a user object and I want to know their security information. 
>   Instead of building an API for looking up security descriptions from a 
> user name that I have to pull out of the user object, I could instead 
> register and adapter from IUser to ISecurityInfo, now I don't need any 
> new APIs, I just so sec_info = ISecurityInfo(the_user).  This form of 
> adaptation is good for the "I have something and want more information 
> about it" use case.  It also adds some flexibility, the workings of the 
> adapter can change without having to change all the client code as you'd 
> have to do if you changed (for example) the parameters an API expected.
> 
> The third way it's used is to make systems pluggable.  You mentioned 
> PyGUI, so say you had a schema describing a data entry form.  You could 
> use adaptation to decide which GUI widget would be used for each field. 
>   Looping over the form fields and adapting each to IWidget and getting 
> back a TextField for a string, CheckBox for a boolean, etc.  Then if the 
> user has a nice TextField object with spell checking, they could just 
> plug in a different adapter and all their fields would get the new 
> widget without PyGUI having to support a plug-in framework.

This is where I start getting nervous about adaptation, that it is used 
for a few too many things.

For instance, ISecurityInfo(the_user) is essentially providing 
magic-method-like introspection, except potentially you don't need the 
cooperation of the object, and the fetching has a namespace (a method 
has only a name, but ISecurityInfo actually lives someplace specific).

Those are useful features, but is it adaptation?  If not adaptation, 
what do we call it?  I suspect, given the right name, some aspects of 
the implementation can be streamlined and it will become a much more 
sensible operation to people.  Magic methods are workable but hardly 
perfect, and the typical way they usually get used is that some function 
knows about all "normal" types (especially the fundamental types that 
can't have methods added to them) and falls back on a magic method. 
It's not pretty, though honestly I don't know of particularly pretty 
techniques that other languages use.

The last item feels much more comfortable to me as generic functions 
(like in PJE's RuleDispatch).  It covers the use cases where 
multi-adaptation seems to pop up, and to me multi-adapatation just looks 
like the poor man's generic functions implemented in terms of 
adaptation, because adaptation systems (well, Zope interfaces) have a 
nice declarative system and pattern matching facilities.  But leveraging 
that just to avoid real generic functions seems wrong to me.

Adaptation-that-is-actually-adaptation feels more like views to me.  You 
need a specific interface, but you want to be able to accept objects 
that are isomorphic to that interface.  Finding the right view (aka 
adapter) is something that calls for all the kinds of mechanisms Zope 
interfaces have -- interfaces and declarations of views/adapters.  But 
the promises that a view makes are much stronger than what an adapter 
makes in current systems.  A view can only be a subset of what the 
original object provides, but that doesn't seem to be the norm for Zope 
adapters.

That said... is ISecurityInfo(the_user) a view of the user?  Possibly, 
depending on how it is implemented.  If it is implemented as "return 
self.security_info" then no, unless the_user.security_info is read-only. 
  If the adapter is a proxy object that forwards everything to 
"the_user.security_info", then yes.  But something still feels weird to 
me about it.  And I suppose ISomeInterface(obj1, obj2) could create 
something that is a subset of the two objects.  Hrm... the whole thing 
makes me feel funny, though.  Maybe it's that I want adaptation to be 
reversable.

-- 
Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org


More information about the Python-3000 mailing list