在Python中,迭代器、生成器毫无疑问是最有用的特性之一,功能也非常强大,在Python中经常出现,但是常常被我们忽视或者说不太理解它们的原理机制,本文就围绕迭代器、生成器、可迭代对象这些来详细阐述一下它们之间的关系以及它们的强大之处。
可以使用for···in···语句进行循环的对象,就是可迭代对象,像我们熟知的字符串、列表、元组、字典等都属于可迭代对象。
我们可以使用isinstance()来判断。
代码如下(示例):
from typing import Iterable, Iterator, Generator
print(isinstance(1234, Iterable))
print(isinstance('name', Iterable))
print(isinstance([1, 2, 3], Iterable))
print(isinstance((1,), Iterable))
print(isinstance({'key': 'val'}, Iterable))
print(isinstance({'s1', 's2'}, Iterable))
###结果为:
False
True
True
True
True
True
根据结果就可以得到结论上述常见字符串、列表、元组、字典等都是可迭代的,而int类型的是不可迭代的。
可迭代对象含有方法__iter__,所以创建可迭代的类即给类定义一个__iter__这样方法。
代码如下(示例):
from typing import Iterable, Iterator, Generator
class Car:
def test(self, name):
return name
def __iter__(self):
pass
car = Car()
print(isinstance(car, Iterable))
###结果为:
True
迭代器是可迭代对象的子集,所以迭代器需要有方法__iter__,还需要有方法__next__。
可迭代对象和迭代器的区别就在于next()方法,迭代器可以通过next()方法不断的获取下一个值,直到所有元素全部输出完之后,返回StopIteration异常才会停止。
代码如下(示例):
from typing import Iterable, Iterator, Generator
print(isinstance('name', Iterator))
print(isinstance([1, 2, 3], Iterator))
print(isinstance((1,), Iterator))
print(isinstance({'key': 'val'}, Iterator))
print(isinstance({'s1', 's2'}, Iterator))
###结果为:
False
False
False
False
False
根据结果就可以得到结论上述常见字符串、列表、元组、字典等都不是迭代器。
代码如下(示例):
from typing import Iterable, Iterator, Generator
print(isinstance(iter('name'), Iterator))
print(isinstance(iter([1, 2, 3]), Iterator))
print(isinstance(iter((1,)), Iterator))
print(isinstance(iter({'key': 'val'}), Iterator))
print(isinstance(iter({'s1', 's2'}), Iterator)
###结果为:
True
True
True
True
True
代码如下(示例):
from typing import Iterator
class Car:
def test(self, name):
return name
def __next__(self):
pass
def __iter__(self):
pass
car = Car()
print(isinstance(car, Iterator))
###结果为:
True
代码如下(示例):
a = [1, 2]
print(isinstance(a, Iterator))
b = iter(a)
print(isinstance(b, Iterator))
print(next(b))
print(next(b))
print(next(b))
###结果为:
False
True
1
2
Traceback (most recent call last):
File "D:\xxxx\tete.py", line 15, in <module>
print(next(b))
StopIteration
生成器又是迭代器的子集,所以实现生成器除了需要方法__iter__、方法__next__还需要有关键yield。
代码如下(示例):
from typing import Iterable, Iterator, Generator
g = (i for i in range(10))
print(isinstance(g, Generator))
###结果为:
True
代码如下(示例):
def func(end):
start = 0
while start < end:
yield start
start += 1
print(isinstance(func(4), Generator))
###结果为:
True