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

Serhiy Storchaka storchaka at gmail.com
Tue Sep 11 02:53:42 EDT 2018


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}



More information about the Python-ideas mailing list