迭代器 : 区分 : 可迭代 ---> 实现了__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 将不会让协程交替运行
原文地址:https://www.cnblogs.com/hhj-study-10years/p/8955593.html
时间: 2024-10-07 08:16:21