[Python-ideas] __iter__(), keys(), and the mapping protocol

Alex Walters tritium-list at sdamon.com
Wed Sep 12 06:44:37 EDT 2018



> -----Original Message-----
> From: Python-ideas <python-ideas-bounces+tritium-
> list=sdamon.com at python.org> On Behalf Of Serhiy Storchaka
> Sent: Tuesday, September 11, 2018 2:54 AM
> To: python-ideas at python.org
> Subject: Re: [Python-ideas] __iter__(), keys(), and the mapping protocol
> 
> 11.09.18 05:04, Elias Tarhini пише:
> > This has been bouncing around in my head for a while regarding the
> > requisite keys() method on mappings:
> >
> > How come the ** unpacking operator, a built-in language feature, relies
> > on a non-dunder to operate?
> >
> > To me, I mean to say, requiring that classes implement keys() – a method
> > whose name is totally undistinguished – in order to conform to the
> > mapping protocol feels like a design running counter to Python's norm of
> > using dunders for everything "hidden". I am not sure if it feels dirty
> > to anybody else, however. Interestingly, the docs already say
> > <https://docs.python.org/3/reference/datamodel.html#object.__iter__>
> > that /[f]or mappings, [__iter__()] should iterate over the keys of the
> > container/, but it of course is not enforced in any way at present.
> >
> > So, then — how about enforcing it? Should __iter__(), for the reasons
> > above, replace the current purpose of keys() in mappings?
> >
> > I'm not properly equipped at the moment to mess around with CPython
> > (sorry), but I assume at a minimum this would entail either replacing
> > all instances of PyMapping_Keys() with PyObject_GetIter()or
> > alternatively changing PyMapping_Keys() to call the latter.
> >
> > Does it sound like a reasonable change overall?
> 
> Dict has keys(), while list doesn't. If use __iter__() instead of
> keys(), {**m} or dict(m) will give unexpected result for some
> non-mappings, like m = [0, 2, 1]:
> 
>  >>> {k: m[k] for k in m}
> {0: 0, 2: 1, 1: 2}
> 

I don't think switching to __iter__ will cause dict(a_list) to produce anything other than what it does now - a traceback if the list is anything but a list of pairs.  I think if we were to go forward with switching map-unpacking to __iter__, it would produce confusing mappings like you show in your example.

I don't think it’s a good idea to switch to __iter__, or even make a dunder method for keys.  The dunder methods are dunder methods because they are not generally directly useful.  I don't see a major problem with having the mapping api call keys() - this is not a next()/__next__() situation, where the method is not generally directly useful.

> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/



More information about the Python-ideas mailing list