定义一个可迭代对象
Python中的Iterable译为可迭代对象,在一个类中,只要定义了一个__iter__
,那么他就是一个可迭代对象
1 | from collections.abc import Iterable, Iterator |
一个可迭代对象可以通过for 循环触发迭代,for循环一个对象,就是运行他的__iter__
,在上述文件后添加如下内容,
1 | a = A() |
运行结果为
1 | entered iter |
注意,entered iter已经被打印了
但是报错了,报错的内容为iter
函数(iter() 调用的就是__iter__
)返回的内容不是一个迭代器,也就是说,for循环的操作是,通过__iter__
函数返回一个迭代器,然后开始逐个输出迭代器中的内容
我们尝试返回一个迭代器,我们知道,一个list是可以被for循环输出的,因此,一个list的__iter__
返回的内容必然是一个可以迭代出list中内容的迭代器
1 | from collections.abc import Iterable, Iterator |
输出结果
1 | 1 |
定义一个迭代器
在一个类中,只要定义了一个__iter__
,那么他就是一个可迭代对象,是一个可以通过for 关键字来触发__iter__
函数运行的可迭代对象。
虽然他是一个可以被for触发的一个可迭代对象,但是目前还不知道迭代的内容是什么,所以我们需要定义迭代的内容,这就是迭代器
上面我们知道__iter__
返回的内容需要是一个迭代器,只要一个类中定义__next__
方法,他就是一个迭代器,因此我们需要在__iter__
中返回自己即可
1 | from collections.abc import Iterable, Iterator |
输出是内容是,无穷无尽的1
1 | 1 |
这说明,for的确是先调用__iter__
,然后再调用__next__
。
想要让循环停止,需要给一个判定条件,抛出StopIteration
异常,即可
生成器
通过上面迭代器的定义可知,写一个迭代器还是比较复杂的,需要定义两个魔法函数,有一种特殊的迭代器,他叫生成器,他的写法就十分的简单
在函数中,把return 改为yield 即可
1 | def fibonacci(n): # 生成器函数 - 斐波那契 |
fibonacci(10)
不会直接运行,每调用一次next,函数就执行到yield把值返回。