码迷,mamicode.com
首页 > 其他好文 > 详细

007-迭代器-生成器-协程

时间:2018-04-27 02:31:51      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:主线程   bsp   nbsp   gevent   div   正是   本质   注意   遍历   

迭代器 :
    区分 : 可迭代 ---> 实现了__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-迭代器-生成器-协程

标签:主线程   bsp   nbsp   gevent   div   正是   本质   注意   遍历   

原文地址:https://www.cnblogs.com/hhj-study-10years/p/8955593.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!