On Tue, Aug 29, 2017 at 4:53 AM, Stefan Ram <r...@zedat.fu-berlin.de> wrote: > r...@zedat.fu-berlin.de (Stefan Ram) writes: >>The "The Python Library Reference, Release 3.6.0" (LIB) says: >>»it must support the sequence protocol (the >>__getitem__() method with integer arguments >>starting at 0).«. >>But in the "The Python Language Reference, Release 3.6.0" >>(LANG) this is called »old sequence iteration« or »old-style >>iteration« with the (new) sequence protocol being augmented >>by »__len__«. > > Can one say that the authoritative test for being »iterable« > and being »a sequence« is testing whether the object is an > instance of »collections.abc.Iterable« and > »collections.abc.Sequence«, respectively? > > Some parts of the references explain that implementing the > sequence protocol means to have a »__getitem__« method and > possibly also a »__len__« method. But, by inheritance, > »collections.abc.Sequence« seems to require /more/. I.e., > >>>> import collections.abc > >>>> d = { 1: 2 } > >>>> d.__len__ > <method-wrapper '__len__' of dict object at 0x00000000023578B8> > >>>> d.__getitem__ > <built-in method __getitem__ of dict object at 0x00000000023578B8> > >>>> isinstance( d, collections.abc.Sequence ) > False > > And the reference does /not/ list dictionary under "Sequences".
A dictionary isn't a sequence. At very least, you have to be able to start with d[0] and go up from there; and that is indeed a valid *iterable* protocol: >>> class Demo: ... def __getitem__(self, item): ... item = int(item) ... if 0 <= item < 10: return item * item ... raise IndexError ... >>> list(Demo()) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] But that isn't a sequence still. Be careful that you aren't looking at *iterable* protocol instead. ChrisA -- https://mail.python.org/mailman/listinfo/python-list