Python Iterables, Iterators, and Generators

Python iterable object (Iterable), iterator (Iterator) and generator (generator) are three different concepts.
Iterable object : The instantiated class contains __iter__ function
Iterator : The instantiated class contains __iter__ and __next__
Generator : To turn a function into a generator, just add the yield keyword to the function

The for loop essentially performs two processes, __iter__ is called and __next__ is acquired.
One thing to note here: if a class contains __iter__, the for loop must be able to act on the object of the class, but if iter returns itself, then the class must declare a __next__ function (the object is also an iterative device). Otherwise, an error is reported (TypeError: iter() returned non-iterator of type 'test'). Conversely, if iter returns another iterator, it is also feasible without next, in which case the object is just an iterable object, not an iterator.

The for loop can act on any iterable object .
The iterator must be an iterable object , and the iterable object is not necessarily an iterator (it is not an iterator when next cannot be called). For example, containers such as list and dict are iterable objects , but not iterators (can be converted to iterators with iter() ). The reason for this design is to consider the iterator as an infinite data stream, which the container cannot do.
A generator can be regarded as a special type of iterator, which has all the properties and methods of an iterator, and is usually generated by adding yield to a function . When using it, instead of calculating all the results at one time, it stores the code and state of the function and waits for the next calculation.

The test code is as follows:

from collections import Iterator, Iterable


class test:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        # return self
        return iter(range(5))

    # def __next__(self):
    #     if self.data > 5:
    #         raise StopIteration
    #     else:
    #         self.data += 1
    #         return self.data

    def gen(self, num):
        i = 0
        while i < num:
            yield self.data
            i += 1


t = test(1)

# for i in t.gen(2):
#     print(i)

# for _ in range(2):
#     print(next(t))

for i in t:
    print(i)

print(type(t.gen(2)))
print(isinstance(t, Iterator))
print(isinstance(t, Iterable))

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325682468&siteId=291194637