python实习总结(yeild,async,azwait和协程)
作者:==今天写代码了吗 发布时间:2021-06-16 20:40:45
一、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 + 1
for 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的切换开销。协程好于多线程的原因。
如何使用协程?
多进程+协程下,避开了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
<generator object simple_corotine at 0x0000000000A8A518>
>>> next(my_coro)#先激活生成器,执行到yield val语句#或者使用send(None)也可以激活生成器
---->coroutine started
>>> my_coro.send(24)#向其中传入值,x = yield
---->coroutine recvied: 24
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration#当生成器执行完毕时会报错
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使用方法 ↩︎
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
来源:https://blog.csdn.net/yue_yue0/article/details/118499351
猜你喜欢
- 下面的request.servervariables例子都是服务器探针采用的asp代码本机ip:<%=request.serverva
- 下面列出了asp远程网页数据采集程序中经常用到的函数,很实用,特别是正则表达式过滤函数。包括了使用xmlhttp采集远程网页内容,使用ado
- 本文实例讲述了python实现上传样本到virustotal并查询扫描信息的方法。分享给大家供大家参考。具体方法如下:import simp
- WaitGroup的用途:它能够一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成。官方对
- 如题:我写入关键字到数据库,多的时候用|隔开了,我提取再做相关文章搜索的时候,我怎么提取用|隔开的文字啊,这样我就好用关键字做搜索啊 回复:
- 最近在内部讨论关于”完美三栏”的话题,看到一篇”In Search of the Holy Grail“,相当的好.故此翻译之.In Sea
- 发现ie7的空格间距要比ie6/firefox/opera的都要宽一点。比如有时候排版的时候,我会采用简单的空格来分隔。<div&nb
- 可以输入的下拉菜单,不错的一个效果,相信asp之家给大家收集的这个代码会有不少人需要!<html> <head> &
- CSS 盒模型网页设计中的每个元素都是长方形的盒子。盒子的尺寸是怎样精确计算的,请看下图:如果是 Firebug 用户的话(基本和前端有关的
- 由于工作需要,这两天在看GOOGLE MAP 的 API,需要在公司的网站上使用地图。今天把看过之后的一点使用方法,跟大家一起分享:演示地址
- css可以处理16,777,216颜色,可以使用名字、rgb值或十六进制代码。red红色等同于 rgb(255,0,0) &nbs
- MySQL有6种日志,监控数据库系统的时候必须知道select日志slow select日志变更日志二进制变更日志(binlog) 
- 1.H5 download属性function downFile(content, filename) { // 创建隐藏的可下
- 如果管理网络设备很多,不可能靠人力每天去登录设备去查看是否在线。所以,可以利用python脚本通过每天扫描网络中的在线设备。可以部署在服务器
- 嵌套模板(Nested Template),其实就是基于另一个模板创建的模板。要创建嵌套模板,首先要保
- 介绍据官方所述,mango Cache是对Guava Cache基于go的部分实现,同时mangoCache参考了Caffeine以及go-
- 一、基础介绍Go 是静态(编译型)语言,是区别于解释型语言的弱类型语言(静态:类型固定,强类型:不同类型不允许直接运算)例如 python
- 虚拟环境管理创建虚拟环境#默认路径下创建虚拟环境conda create -n pythonVirtual python=x.x # -n:
- 在印刷排版中“point”是一个绝对的单位,它等于 1/72 英寸。可以用尺子丈量的,物理的英寸。但在CSS中pt的含义
- overflow:hidden 用在div上时很好用,但直接用在td上,好像没有任何效果。td中的文本过长时依然自动换了一行像下面这要设定一