Python高级——多线程_07_协程(修饰器)
迭代
概念:通过for循环遍历取值的过程
可迭代对象:通过fo循环遍历取值的对象
可迭代对象的本质:
遍历可迭代对象的时候其实获取的是可迭代对象的迭代器,
然后通过迭代器获取对象中的数据
元组,列表,字典,字符串,集合,range
迭代器
优点:占用极小内存空间, 存储的是生成数据的方式而不是结果
记录当前数据的位置,方便取下一个位置的值
实现 延迟计算/懒惰计算
操作:
1.取出对象手元祖的位置信息放入迭代器 返回迭代器
i = iter(data) iter返回迭代器 ==》可迭代对象.__iter__()
2.不断通过迭代器去取出下一个元素的值 直到迭代完成
则抛出异常 StopIteration 停止迭代异常
print(next(i)) next进行取值==》可迭代对象.__next__()
如果迭代完成则抛出异常
raise StopIteration
自定义迭代器
1.使用__iter__提供迭代器 返回迭代器对象self
2.使用__next__提供下一个元素的值
判断是否为迭代器
for collections import Iterator
isinstance(对象,Iterator) 返回True/False
判断是否为迭代对象:for collections import Iterable
isinstance(对象,Iterable) 返回True/False
结论:
迭代器一定是可迭代对象
可迭代对象 不一定是迭代器 <可迭代对象只需要实现__iter__方法提供迭代器>
生成器
场景:保证代码只执行一部分就返回
概念:特殊的迭代器,不需要实现iter和next,仍然可以使用iter、next和for循环
分类
1.生成器表达式 列表推导式[]-->()
生成器表达式和列表推导式的异同:
不同:产生对象不同
生成器占用内存更少,因为生成器存储的是算法
相同:使用结果一致
2.生成器函数
调用产生生成器对象
如果函数有yield语句,就是生成器模板
yield:
暂时挂起当前函数 将后面的值返回给调用生成器的地方
当再次调用生成器函数的时候 会回复当前函数继续执行
生成器内部自动实现
raise StopIteration __next__ __iter__
一般在生成器中不是用return 关键字
一旦使用就会结束生成器的迭代过程,获取方式通过捕获异常的value进行取值
使用send可以进行传参
格式,生成器对象.send(参数)
第一次调用生成器必须使用next
通过传入不同的参数可以控制生成器执行的逻辑
唤醒生成器
next(生成器对象)
生成器.send(数据)
异同:
next是函数 send是方法
next不能传参 send可以传参
第一次只能next 其余地方随意使用<参数的值只有yield才能接收>
因为send执行时必须从yield开始执行
同:
获取到下一个元素的值
协程
轻量级线程
进程 线程 是操作系统级别的多任务机制
协程是 用户级别的多任务机制<用户程序自己实现>
使用场景:多任务数量很多时/网络型程序
greenlet
对于yield的简单封装使用
通过switch进行切换
gevent
网络异步并发库
spawn(函数名,参数(args),参数(kwargs))创建协程
1.使用gevent.sleep进行自动切换
2.
【gevent文档规定 要求放在源代码开始处】
form gevent import monkey
monkey.patch_all() #补丁
将默认阻塞变非阻塞:recv / accept / time.sleep
没有设置前自动阻塞,不能切换
在所有协程之前完成前 保持主进程的存活
对象.join
gevent.joinall([对象1,对象2])