python实习总结(yeild|python实习总结(yeild,async,azwait和协程)
目录
- 一、yield使用简析
- 二、async和await的使用
- 1.什么是进程、协程、异步?
- 2.如何处理200W数量的url,把所有的url保存下来?
- 3.使用async的await和gather
- 三、协程的理解
- 总结
一、yield使用简析 yield是一个生成器generator,返回一个interable对象。
该对象具有next()方法,可以通过next()查看接下来的元素是什么。
1.interable对象 ,可以遍历的对象,如: list,str,tuple,dict,file,xrange等。
2.yield的作用是什么?只是循环里面的获取中间变量的一个方法,把想要的变量每次使用yield保存起来直至循环结束,循环结束得到了一个generator对象
3.为什么使用yield?使用yield,一个函数改写成generator,便具有了迭代的能力,比起用类的实例保存状态计算下一个需要迭代的值,代码更加简洁,执行流程十分简单。
4.如何判断yield的类型?
def fab(max): n, a, b = 0, 0, 1 while n < max: yield b# 使用 yield# print b a, b = b, a + b n = n + 1for n in fab(5): print n
fab不是generator,fab(5)是generator。
好比类的定义和类的实例的区别。
>>>import types >>> isinstance(fab, types.GeneratorType) False >>> isinstance(fab(5), types.GeneratorType) True
fab 是无法迭代的,而 fab(5) 是可迭代的。
>>>from collections import Iterable >>> isinstance(fab, Iterable) False >>> isinstance(fab(5), Iterable) True
5.yield在文件读取的应用?
如果字节使用read()读取一个文件,会导致不可预测的内存占用。好的方法是使用yield,固定长度的缓冲区来不断读取文件,生成读文件的迭代的generator。
def read_file(fpath): BLOCK_SIZE = 1024 with open(fpath, 'rb') as f: while True: block = f.read(BLOCK_SIZE) if block: yield block else: return
二、async和await的使用
1.什么是进程、协程、异步?
- 协程是什么?
协程切换时候,将寄存器和栈保存在其他地方,当返回的时候,恢复原先保存的寄存器上下文和栈。
- 为什么使用协程?
不管是多进程还是多线程,每次阻塞、切换陷入系统调用。
CPU跑操作系统的调度程序,调度程序决定运行哪一个进程(线程)。
线程非常小心的处理同步问题,而协程完全不存在这个问题。
对于CPU而言,多协程是单线程,CPU不会考虑调度、切换上下文,省去CPU的切换开销。协程好于多线程的原因。
- 如何使用协程?
2.如何处理200W数量的url,把所有的url保存下来?
- 单进程+单线程
- 单进程+多线程:开十个线程,速度不能提高十倍。线程的切换是有开销的,无能无限的创建线程。
- 多进程+多线程:多进程的每个进程占用一个CPU,多线程一定程度上绕过了阻塞时间,所以相比单进程的多线程效率更高。
- 协程
3.使用async的await和gather
- await接受一个协程列表,返回done、pending两个列表。done是已经完成的协程,pending是仍在跑的协程。通过.result()获取完成的结果
- gather以gather(cro1, cro2, cro3, cro4…)的方式接受协程,返回的是一个结合了这么多个任务的协程。
async的使用:https://blog.csdn.net/qq_29785317/article/details/103294235
async def func1(num):print('--func1 start--')await asyncio.sleep(num)print('--func1 done--')return 'func1 ok'async def func2(num):print('--func2 start--')await asyncio.sleep(num)print('--func2 done--')return 'func2 ok'async def main():task1 = asyncio.ensure_future(func1(3))task2 = asyncio.ensure_future(func2(5))tasks = [task1, task2]res = await asyncio.gather(*tasks)return res# done, pending = await asyncio.wait(tasks)# for t in done:#print(t.result())# print(done)# print(pending)if __name__ == '__main__':loop = asyncio.get_event_loop()result = loop.run_until_complete(main())print(result)```python--func1 start----func2 start----func1 done----func2 done--['func1 ok', 'func2 ok']
三、协程的理解 1.协程的过程
协程中yield是控制流程的方式。
yield同接收器一样,是一个生成器,需要先激活才能使用。
>>> def simple_corotine():...print('---->coroutine started')...x = yield#有接收值,所以同生成器一样,需要先激活,使用next...print('---->coroutine recvied:',x)...>>> my_coro = simple_corotine()>>> my_coro
>>> next(my_coro)#先激活生成器,执行到yield val语句#或者使用send(None)也可以激活生成器---->coroutine started>>> my_coro.send(24)#向其中传入值,x = yield---->coroutine recvied: 24Traceback (most recent call last):File "", line 1, inStopIteration#当生成器执行完毕时会报错
2.协程在运行中的四种状态
GEN_CREATE:等待开始执行
GEN_RUNNING:解释器正在执行,这个状态一般看不到
GEN_SUSPENDED:在yield表达式处暂停
GEN_CLOSED:执行结束
>>> def averager():...total = 0.0...count = 0...aver = None...while True:...term = yield aver...total += term...count += 1...aver = total/count...>>> coro_avg = averager()>>> coro_avg.send(None)>>> coro_avg.send(10)10.0>>> coro_avg.send(20)15.0>>> coro_avg.send(30)20.0>>> coro_avg.send(40)25.0
每次循环结束在yield出暂停,直至下一个参数传进来。
3.预激活协程的装饰器(自定义激活的方式)
@装饰器的作用是什么?装饰原有的函数,给原油函数增加一个新的功能和方式。
为什么@可以实现装饰器的功能?函数也是对象,函数可以作为实参传给掐函数。
>>> def coro_active(func):...def inner(*args,**kwargs):...gen = func(*args,**kwargs)...next(gen)#gen.send(None)...return gen...return inner...>>> @coro_active... def averager():...total = 0.0...count = 0...aver = None...while True:...term = yield aver...total += term...count += 1...aver = total/count...>>> coro_avg = averager()>>> coro_avg.send(10) 10.0 >>> coro_avg.send(20) 15.0 >>> coro_avg.send(30) 20.0
4.终止协程和异常处理
当协程的next函数或者send函数发生错误的时候,协程就会终止掉。
需要创建异常捕捉对协程的异常情况进行处理,关闭当前协程。
5.让协程返回值
yield使用方法 ??
总结 本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- 7.9号工作总结~司硕
- python学习之|python学习之 实现QQ自动发送消息
- 逻辑回归的理解与python示例
- python自定义封装带颜色的logging模块
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- Python基础|Python基础 - 练习1
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- Python(pathlib模块)
- 最有效的时间管理工具(赢效率手册和总结笔记)
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则