007-迭代器-生成器-协程
Posted hhj-study-10years
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了007-迭代器-生成器-协程相关的知识,希望对你有一定的参考价值。
迭代器 :
区分 : 可迭代 ---> 实现了__iter__() 的类
可迭代对象 ---> 实现了 __iter__() 的类的实例
迭代器(对象) ---> 实现了 __iter__() 和 __next__() 的类的实例
作用 : 一个可以记住遍历的位置的对象,真正能够获取位置内容的是 next()
如何自定义一个迭代器对象?
要创建两个类,一个普通类,一个迭代器类,合起来就是迭代器对象
定义一个普通类,在普通类中实现 __iter__(),--> 此时,普通类的对象就是可迭代的,但还不能通过 for 将数据一个一个取出来,因为迭代器只是记录了位置。接着,要想能够通过 for 循环取数据,还要在迭代器类中实现 __iter__() 和 __next__() ,魔法方法 next 才是获得数据的关键
想要构造一个迭代器,就要实现它的 __next__(),但这还不够,Python 要求迭代器本身也是可迭代的,所以我们还要为迭代器实现 __iter__(),而 __iter__() 要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的 __iter__() 返回自身 (self) 即可
为什么 __iter__() 要返回一个迭代器?
(配合 for 使用解释)因为当 for 循环一个可迭代对象时,本质是先通过 iter() 获取可迭代对象的迭代器,而 iter() 方法实际上是调用了可迭代对象的 __iter__(),所以如果 __iter__() 不返回一个迭代器的话,iter() 就得不到对象的迭代器,那么 for 也得不到迭代器,没有迭代器,就不能调用迭代器的 next(),就取不了值
for 循环的本质 : ① 当 for 循环的是一个可迭代对象时,先通过 iter() 获取其迭代器,再通过调用 next() 获取对象的值 (调用 next() 实际是调用了迭代器的 __next__())。② 当 for 循环的是一个迭代器时,直接通过 next()获取值
协程(本质是生成器) :
作用 : 在不开辟线程的境况下,在单线程内同时进行多个任务(实际上是同一时刻只能运行一个,但是切换的很快),协程执行是有序的,主线程默认不会等待协程运行结束再退出,需要 joinall()
用法 :
① 不使用框架 : 在函数内使用 yield 关键字 next(函数名())
② greenlet 框架 : g1 = greenlet(函数名1) 函数名1(): g2.switch()
g2 = greenlet(函数名2) 函数名2(): g1.switch()
g1.switch()
③ gevent 框架 : monkey.patch_all()
g1 = gevent.spwan(函数名1)
g2 = gevent.spwan(函数名2)
gevent.joinall([g1,g2])
注意点 : 使用 gevent 时,导入的 time 模块格式必须为 import time
from time import sleep 将不会让协程交替运行
以上是关于007-迭代器-生成器-协程的主要内容,如果未能解决你的问题,请参考以下文章