__next__(for review of this model' essentialssee figure - in this iterable object interface is given priority and attempted first only if no such __iter__ method is foundpython falls back on the __getitem__ scheme and repeatedly indexes by offsets as beforeuntil an indexerror exception is raised version skew noteas described in if you are using python xthe __next__(iterator method just described is named next(in your pythonand the next(ibuilt-in is present for portability--it calls next(in and __next__(in iteration works the same in in all other respects user-defined iterables in the __iter__ schemeclasses implement user-defined iterables by simply implementing the iteration protocol introduced in and elaborated in for examplethe following file uses class to define user-defined iterable that generates squares on demandinstead of all at once (per the preceding notein python define next instead of __next__and print with trailing comma as usual)file squares py class squaresdef __init__(selfstartstop)self value start self stop stop def __iter__(self)return self def __next__(self)if self value =self stopraise stopiteration self value + return self value * save state when created get iterator object on iter return square on each iteration also called by next built-in when importedits instances can appear in iteration contexts just like built-inspython from squares import squares for in squares( )print(iend='for calls iterwhich calls __iter__ each iteration calls __next__ herethe iterator object returned by __iter__ is simply the instance selfbecause the __next__ method is part of this class itself in more complex scenariosthe iterator object may be defined as separate class and object with its own state information to support multiple active iterations over the same data (we'll see an example of this in momentthe end of the iteration is signaled with python raise statement--introduced in and covered in full in the next part of this bookbut which simply operator overloading