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


猜你喜欢
- nn.RNN(input_size, hidden_size, num_layers=1, nonlinearity=tanh, bias=
- 人脸检测方法有许多,比如opencv自带的人脸Haar特征分类器和dlib人脸检测方法等。对于opencv的人脸检测方法,有点是简单,快速;
- 本文实例讲述了Python基于正则表达式实现检查文件内容的方法分享给大家供大家参考,具体如下:这个是之前就在学python,欣赏python
- 在mysql安装目录的bin下, 运行mysql --install MYSQL5查看服务中, 会多一个MYSQL5的服务XAMPP的控制面
- 查看python3.4.1文档,发现对于decimal模块的讲解非常多,由此可见其功能也很强大(下面算是把我认为比较重要的半翻译半学习吧~)
- 需要安装的python库使用python编写程序进行测试MQTT的发布和订阅功能。首先要安装:pip install paho-mqtt测试
- <? // 建立一个指向新COM组件的索引 $word = new C
- 1函数是一种有零个或多个参数并且有一个返回值的程序。在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数
- 如果可以减少过多的外部隔离的API和简化部署的细节 这会是非常好的。在以前的文章中,我解释了"一些使用反向代理的好处&
- 摘要:本文介绍了有关数据表的优化技巧,主要内容有,选择表的类型,打开尽量少的表,锁定表与查询速度的关系以及如何优化表以达到提高查询速度的目的
- Python文件操作和异常处理Python作为一门高级编程语言,为我们提供了丰富的文件操作和异常处理机制。在本文中,我们将从以下几个方面讨论
- 从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例?有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,
- 今天,在项目中遇到一个问题,两个js页面要共享一个就js对象。js全局变量和静态变量都不行,其他苦逼的小农们就不要去强求了。而LZ又不想用c
- Python的命名空间是Python程序猿必须了解的内容,对Python命名空间的学习,将使我们在本质上掌握一些Python中的琐碎的规则。
- 编写Python SDK代码工程目录结构├──── easyhttp
- 第一章:基本的圆角框第二章:透明圆角化背景图片第三章:圆角化图片 第四章:CSS圆角框组件 V1.0序言:在我的文章《超圆滑圆角框的半完美解
- 分区视图联接来自一组成员的水平分区数据,使数据看起来象来自同一张表。SQL Server 2000 区分本地分区视图和分布式分区视图。在本地
- 本文实例讲述了Python实现的合并两个有序数组算法。分享给大家供大家参考,具体如下:思路按位循环比较两个数组,较小元素的放入新数组,下标加
- 如下所示:# -*- coding: utf-8 -*-# 要求:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。def
- ASP中给函数传参确实是个麻烦事,当参数个数特别多的时候(比如有七八个或者更多的参数个数)差不多就要眼冒金星了,一个个的数吧。而且要命的是参