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

Ian Bicking ianb at colorstudy.com
Fri Mar 31 02:11:47 CEST 2006


Guido van Rossum wrote:
>>A collection-specific protocol for testing equality would be reasonable.
> 
> 
> I'm not sure what you mean here. Are you proposing using a different
> method than __eq__()?

No, that a collection that wanted to do a nice equality test might do 
something like:

class Set:
     def __eq__(self, other):
         if not other.__is_collection__():
             return False
         if len(self) != len(other):
             return False
         for item in other:
             if item not in self:
                 return False
         return True

Though in this example "Set([1, 2]) == {1: None, 2: None}" is true, 
which I wouldn't like.  In general mapping and non-mapping collections 
seem fairly different to me.  Though if "Set([(1, None), (2, None)]) == 
{1: None, 2: None}" is true, that's actually perfectly fine to me.  I 
guess I don't like that dictionaries, when treated like sequences, 
reveal only their keys, when that's just a subset of what they are.

>>It doesn't break duck typing, just adds a bit more to the interfaces of
>>collections than purely a bunch of disparate methods.
>>
>>A generic view protocol could maybe handle it too, so you'd ask an
>>object to give a set-like view of itself when comparing that object to a
>>set, and then test that.  And the object could return itself, if it
>>already implemented a set-like view.  Or return None, meaning no such
>>view was possible.  At which point it sounds just like adaptation.
> 
> 
> That's definitely an interesting thought, but I'm not sure if it'll go
> anywhere. I wouldn't want this to turn into the creation of a new set
> object (a copy); if it can't be a view, it should be refused. That's
> different from adaptation. I don't want copies to be created because
> views ought to be lightweight; that's part of the contract for views.
> If the caller doesn't mind a copy to be taken, they should just use
> set(x) directly.

I can't remember if there is an adaptation term related to that.  I seem 
to remember people (where "people" probably means "Jim") referring to 
the fact that for some adaptations "IFoo(IBar(foo)) is foo" is true, 
when foo implements IFoo, whereas for views this would be more-or-less 
implied...?  And I don't know if it is guaranteed that any changes made 
to IBar(foo) will be reflected in foo itself.  I think that isn't 
guaranteed, and that Zope interfaces have some extra things to handle 
the results (Annotatable or something).

The more I think about it, the more views seem like a more explicit and 
constrained form of adaptation.  They are more explicit because they 
generally are accessed in a specific way, like dict.keys().  But if 
views were used for equality, there'd need to be an implicit way to get 
a view too (though I assume that no implicit means of getting a view 
would ever give you something quite like dict.keys(), which is only a 
subset of dict -- but it might give you something like dict.items()). 
Views are more constrained because they have no state and are only 
proxies to some underlying object.

Generally speaking I've remained suspicious of adaptation.  Clearly 
other people have too, since adaptation has long been lingering and 
hasn't become part of mainstream Python (in or out of the standard 
library).  Views as a more conservative kind of adaptation seems like it 
addresses many of the issues -- preserving dynamic typing while also 
allowing for explicit interfaces -- without some of the complexity of 
"full" adaptation.

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


More information about the Python-3000 mailing list