'''
Iterables are any object that, when the iter() method is called (implicitly or not),
returns an iterator (an object with a __next__() method). Sometimes, these
objects can even be the same (as is the case with this example).
'''
'''
This class is an iterable class, because it contains an __iter__() method which
returns an iterator (in this case, itself). Each time the next() method is called,
a value is generated. These values are lazily loaded, like generators, but they
are stored in memory as part of a class instance attribute.
'''
class iterable:
def __init__(self, i, n):
self.i = i
self.n = n
def __iter__(self): # <-- makes this an iterable, and returns an iterator (itself)
return self
def __next__(self):
if self.i < self.n:
tmp = self.i
self.i += 1
return tmp**2
else:
raise StopIteration
y = iterable(1, 10)
for j in y:
# print(y.i) <-- this line prints the value of i when the function returns
print(j)