I’m trying to understand why I can iterate along the string. What I see in the documentation is:
One method needs to be defined for container objects to provide
iteration support:container.__iter__()
Return an iterator object. The object is required
to support the iterator protocol described below. If a container
supports different types of iteration, additional methods can be
provided to specifically request iterators for those iteration types.
(An example of an object supporting multiple forms of iteration would
be a tree structure which supports both breadth-first and depth-first
traversal.) This method corresponds to the tp_iter slot of the type
structure for Python objects in the Python/C API.The iterator objects themselves are required to support the following
two methods, which together form the iterator protocol:iterator.__iter__()
Return the iterator object itself. This is
required to allow both containers and iterators to be used with the
for and in statements. This method corresponds to the tp_iter slot of
the type structure for Python objects in the Python/C API.iterator.next()
Return the next item from the container. If there are
no further items, raise the StopIteration exception. This method
corresponds to the tp_iternext slot of the type structure for Python
objects in the Python/C API.
But…
>>> dir('aa')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__',
'__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip',
'swapcase', 'title', 'translate', 'upper', 'zfill']
I don’t see here any __iter__() or next(). So why does it work?
Iterators were new in Python 2.2. The old method was the sequence protocol (implements
__getitem__with 0-based indices) and still works.