可迭代对象
- 可迭代对象,可以通过循环遍历其中的元素,但是可迭代对象不一定是迭代器,比如说列表就是可迭代对象,但不是迭代器。 ```python from collections.abc import Iterator
li = [1,3,5,7,9]
print(isinstance(li, Iterator))
for i in li: print(i)
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1325594/1594384309741-29b13dd4-41e9-4779-ac3b-157602bf3cba.png#align=left&display=inline&height=60&margin=%5Bobject%20Object%5D&name=image.png&originHeight=137&originWidth=1325&size=31121&status=done&style=none&width=576)
<a name="r3FOL"></a>
#### 迭代器
- 可以通过iter()函数将可迭代对象转为迭代器
- next() 方法可以将迭代器中的元素取出,并且不可逆
- 在元素取完之后,再想取元素就会抛出异常StopIteration,因为已经没有元素可以取出来了,但是如果使用for循环遍历的话,实际上是使用的iter()方法,for可以自动捕获异常从而不会报错
```python
from collections.abc import Iterator
li = [1,3,5,7,9]
li = iter(li)
print(isinstance(li, Iterator))
while True:
print(next(li))
iter()就是对象的iter()魔法方法
- 该方法返回一个可迭代对象
- 只要对象中实现了iter()魔法方法,即可作为可迭代对象
next()就是对象的next()魔法方法
- 可以将迭代器中的元素一个一个的取出
对象只有同时拥有这两种魔法方法才能算迭代器,如果只有iter方法只能作为可迭代对象,并不是迭代器 ```python from collections.abc import Iterator
class MyIterator(Iterator): def init(self, num): self.num = num
def __next__(self):
# 如果num大于0 则返回num -= 1 否则主动抛出异常
if self.num > 0:
self.num -= 1
return self.num
raise StopIteration
def __iter__(self):
# 因为继承的就是Iterator 所以返回本身即是迭代器
return self
my = MyIterator(2)
print(isinstance(my, Iterator))
print(next(my)) print(next(my)) print(next(my))
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1325594/1594386330683-e6ed512c-6725-4caa-bb35-6584a12227d1.png#align=left&display=inline&height=101&margin=%5Bobject%20Object%5D&name=image.png&originHeight=201&originWidth=1243&size=80538&status=done&style=none&width=621.5)
<a name="8kTnz"></a>
#### 生成器
- 当函数使用yield语句时,可将函数挂起,等待下一次的继续运行,功能类似于迭代器。
- 如果一个可迭代对象占用空间特别大,其中元素可以使用某种算法推导出来,则可以使用生成器
```python
from collections.abc import Generator
g = (i for i in range(10))
print(isinstance(g, Generator))
for i in g:
print(i)
- 如果一个函数需要被多次调用,并且可以每次需要传递参数,可以使用yield回调参数然后挂起
- 可以通过send发送参数,实现相互通信
- 生成器函数效率更高,可以按需调用
- 可以通过yield实现协程