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-迭代器-生成器-协程的主要内容,如果未能解决你的问题,请参考以下文章

Python进阶:一文搞懂迭代器生成器协程(附案例)

Python高级语法——协程/迭代器/生成器——学习心得笔记

python基础-------迭代器,生成器,协程函数

python基础----迭代器生成器协程函数

迭代器--》生成器--》协程的关系与区别

多任务-协程