python async_python async with和async for的使用

网上async with和async for的中文资料比较少,我把PEP 492中的官方陈述翻译一下。

异步上下文管理器”async with”

异步上下文管理器指的是在enter和exit方法处能够暂停执行的上下文管理器。

为了实现这样的功能,需要加入两个新的方法:__aenter__ 和__aexit__。这两个方法都要返回一个 awaitable类型的值。

异步上下文管理器的一种使用方法是:

class AsyncContextManager:

async def __aenter__(self):

await log('entering context')

async def __aexit__(self, exc_type, exc, tb):

await log('exiting context')

新语法

异步上下文管理器使用一种新的语法:

async with EXPR as VAR:

BLOCK

这段代码在语义上等同于:

mgr = (EXPR)

aexit = type(mgr).__aexit__

aenter = type(mgr).__aenter__(mgr)

exc = True

VAR = await aenter

try:

BLOCK

except:

if not await aexit(mgr, *sys.exc_info()):

raise

else:

await aexit(mgr, None, None, None)

和常规的with表达式一样,可以在一个async with表达式中指定多个上下文管理器。

如果向async with表达式传入的上下文管理器中没有__aenter__ 和__aexit__方法,这将引起一个错误 。如果在async def函数外面使用async with,将引起一个SyntaxError(语法错误)。

例子

使用async with能够很容易地实现一个数据库事务管理器。

async def commit(session, data):

...

async with session.transaction():

...

await session.update(data)

...

需要使用锁的代码也很简单:

async with lock:

...

而不是:

with (yield from lock):

...

异步迭代器 “async for”

一个异步可迭代对象(asynchronous iterable)能够在迭代过程中调用异步代码,而异步迭代器就是能够在next方法中调用异步代码。为了支持异步迭代:

1、一个对象必须实现__aiter__方法,该方法返回一个异步迭代器(asynchronous iterator)对象。

2、一个异步迭代器对象必须实现__anext__方法,该方法返回一个awaitable类型的值。

3、为了停止迭代,__anext__必须抛出一个StopAsyncIteration异常。

异步迭代的一个例子如下:

class AsyncIterable:

def __aiter__(self):

return self

async def __anext__(self):

data = await self.fetch_data()

if data:

return data

else:

raise StopAsyncIteration

async def fetch_data(self):

...

新语法

通过异步迭代器实现的一个新的迭代语法如下:

async for TARGET in ITER:

BLOCK

else:

BLOCK2

这在语义上等同于:

iter = (ITER)

iter = type(iter).__aiter__(iter)

running = True

while running:

try:

TARGET = await type(iter).__anext__(iter)

except StopAsyncIteration:

running = False

else:

BLOCK

else:

BLOCK2

把一个没有__aiter__方法的迭代对象传递给 async for将引起TypeError。如果在async def函数外面使用async with,将引起一个SyntaxError(语法错误)。

和常规的for表达式一样, async for也有一个可选的else 分句。.

例子1

使用异步迭代器能够在迭代过程中异步地缓存数据:

async for data in cursor:

...

这里的cursor是一个异步迭代器,能够从一个数据库中每经过N次迭代预取N行数据。

下面的语法展示了这种新的异步迭代协议的用法:

class Cursor:

def __init__(self):

self.buffer = collections.deque()

async def _prefetch(self):

...

def __aiter__(self):

return self

async def __anext__(self):

if not self.buffer:

self.buffer = await self._prefetch()

if not self.buffer:

raise StopAsyncIteration

return self.buffer.popleft()

接下来这个Cursor 类可以这样使用:

async for row in Cursor():

print(row)

which would be equivalent to the following code:

i = Cursor().__aiter__()

while True:

try:

row = await i.__anext__()

except StopAsyncIteration:

break

else:

print(row)

例子2

下面的代码可以将常规的迭代对象变成异步迭代对象。尽管这不是一个非常有用的东西,但这段代码说明了常规迭代器和异步迭代器之间的关系。

class AsyncIteratorWrapper:

def __init__(self, obj):

self._it = iter(obj)

def __aiter__(self):

return self

async def __anext__(self):

try:

value = next(self._it)

except StopIteration:

raise StopAsyncIteration

return value

async for letter in AsyncIteratorWrapper("abc"):

print(letter)

为什么要抛出StopAsyncIteration?

协程(Coroutines)内部仍然是基于生成器的。因此在PEP 479之前,下面两种写法没有本质的区别:

def g1():

yield from fut

return 'spam'

def g2():

yield from fut

raise StopIteration('spam')

自从 PEP 479 得到接受并成为协程 的默认实现,下面这个例子将StopIteration包装成一个RuntimeError。

async def a1():

await fut

raise StopIteration('spam')

告知外围代码迭代已经结束的唯一方法就是抛出StopIteration。因此加入了一个新的异常类StopAsyncIteration。

由PEP 479的规定 , 所有协程中抛出的StopIteration异常都被包装在RuntimeError中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

本文标题: python async with和async for的使用

本文地址: http://www.cppcns.com/jiaoben/python/262859.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python将dataframe写入csv_Pandas dataframe数据写入文件和数据库

转自:http://www.dcharm.com/?p584Pandas是Python下一个开源数据分析的库,它提供的数据结构DataFrame极大的简化了数据分析过程中一些繁琐操作,DataFrame是一张多维的表,大家可以把它想象成一张Excel表单或者Sql表。之前这篇文章已经介绍了从…

java字节输入与字符输入_Java中的字节输入出流和字符输入输出流

Java中的字节输入出流和字符输入输出流下面哪个流类属于面向字符的输入流( )A BufferedWriterB FileInputStreamC ObjectInputStreamD InputStreamReader解析:IO流(1)字节输入流基类:InputStreamFileInputStream、ByteArrayInputStream、PipedInputStrea…

java不同垃圾回收器_细述 Java垃圾回收机制→Types of Java Garbage Collectors

本文非原创,翻译自Types of Java Garbage Collectors在Java中为对象分配和释放内存空间都是由垃圾回收线程自动执行完成的。和C语言不一样的是Java程序员不需要手动写垃圾回收相关的代码。这是使得Java如此流行,同时也是Java能帮助程序员写出更好的Java应…

python控制流代码怎么用_Python学习笔记控制流的元素

随笔记录方便自己和同路人查阅。#------------------------------------------------我是可耻的分割线-------------------------------------------控制流语句的开始部分通常是‘’关键字‘、’“条件”,接下来是一个代码块,称为“子句”。在开始学习具…

js修改地址栏url_不同寻常的地址栏过渡

前几天,我在推特上看到这样一张图。原来地址栏还能这么玩,瞬间就觉得自己弱爆了。然后我决定去实现一下这个效果,然后做成一个库。画了一个晚上,终于做好了。这是最后的成果。这个库使用非常的简单。你只需要,yarn add…

linux php和java环境变量配置_Linux下Java环境变量的安装与配置

安装以JDK1.6.0_43为例增加可执行权限 chmod x jdk-6u43-linux-x64.bin,执行 ./jdk-6u43-linux-x64.bin 生成目录jdk1.6.0_43拷贝到/usr/share下,mv jdk1.6.0_43 /usr/share另外,jdk-6u43-linux-x64.bin将所有文件解压缩到当前目录的jdk$veri…

kaggle数据集_ArXiv170万篇论文数据集上线Kaggle!

大数据文摘出品学术圈的朋友对ArXiv肯定都不陌生。在将近30年的时间里,ArXiv通过公开访问学术文章为公众和研究社区提供了一个更高效的学术成果沟通平台,从物理学到计算机科学的许多子学科,以及介于两者之间的所有内容,包括数学&a…

java检测tomcat宕机_Tomcat意外宕机分析

之前在网上看过一篇文章,是讲Tomcat进程意外退出的,我看完感觉好奇,自己也测试了下,果然是有这种问题,所以自己也借此总结一下。先简单说下测试过程,先创建一个web服务启动 test.sh,内容如下&am…

万能驱动xp离线版_教你用SC封装软件来封装XP系统

今天我们来讲解一下如何用SC软件来封装XP系统。今天的讲解只演示基本的SC封装软件,具体的封装前的准备工具,我们不进行讲解,当然前期的准备工作也是有很多,首先我们先要安装虚拟机软件,并在虚拟机上面安装好原版的XP系…

java dispo lock_java实现文件上传和下载(1)

原理: 使用html 的 标签,提交form 的几个属性必须为: methodpost encTypemultipart/form-data;组件:smartUpload或者commons fileuploadsmartUpload代码实现1。文件预览function showImage(obj){var strobj.value;$("#id").html(&q…

剪板机自动上下料_机器人联轴器,用于机器人自动化上下料

关注点击蓝字,关注我吧纤薄型机器人联轴器,可搬运重量范围从 1kg 至 1,000kg,用于高效机器人自动化机床上下料,多年来受到广泛认可。紧凑型微型联轴器适合于最近迅速发展的小型机器人应用领域。无人操作时工艺可靠性高模块的特殊混…

java 格式化 布尔型_Java基础篇(1)-格式化

本文目录:十进制数字格式化——DecimalFormat数字格式化基类——NumberFormat字符串格式化类——String.format()Linux输出格式化——printf1. 十进制数字格式化(DecimalFormat)decimal是对数字进行格式化,比如取2位小数,这是最常见的。Java提…

python3手机脚本教学_python+adb命令实现自动刷视频脚本案例

python小白第一次发博客,自己自学了一下写了一个demo,可能语法啥的不够标准,毕竟没有真正学过python主要用到的是import os #os包用于运行cmd命令adb shell #这个有很多命令我们主要是模拟滑动直接看代码吧手机要先连接电脑打开usb调试模式# …

java关于泛型的实验代码_[改善Java代码]强制声明泛型的实际类型

Arrays工具类有一个方法asList可以把一个变长参数或数组变成列表,但是它有一个缺点:它所生成的List长度是不可改变的,而这在我们的项目开发中很不方便.importjava.util.Arrays;importjava.util.List;public classClient {public static voidmain(String[] args) {String[] strA…

一旦有辞职念头就干不长了吗_每天都有辞职不想上班的冲动,你有吗?

我从大学毕业到今天,工作的时间将近10年了。直到现在,我还经常有辞职的想法。我觉得现在职场真的不好混,不如意的事情十之八九,有了辞职冲动是非常正常的,不必一上来就刻意的否定,或者克制。依照我的职场经…

mysql 序号_脚本搭建Nginx、Redis、MySql、Maven

当你面对一个全新的Linux系统时,是如何部署搭建项目环境呢?是否是一个一个软件安装呢?小编在往期文章中介绍了相关软件的安装方法,但是你是否发现不同的软件安装下来是否会出现问题呢?今天就教大家如何使用脚本一键安装…

mysql数据库压缩备份_MySQL数据库之mysql数据库备份命令分享(mysql压缩数据库备份)...

本文主要向大家介绍了MySQL数据库之mysql数据库备份命令分享(mysql压缩数据库备份) ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助。备份MySQL数据库的命令复制代码 代码如下:mysqldump -hhostname -uusername -ppassword databasename …

mysql数据库子查询的使用_MySQL数据库使用子查询方式更新数据优化及思考

【环境介绍】云数据库MySQL 5.7【背景描述】业务需要:需要对16370077的表数据进行更新部分数据操作UPDATE P_MOXXXX_REXXXX SET FISAVAILABLE 1 WHERE FREG_ID IN (SELECT FREG_ID FROM P_MOXXXX_REXXXX_UPDATE_TEMP);【按照正常流程更新数据操作】使用archery的SQ…

业务中台建设与应用_容易网业务中台建设,助力企业数字化转型

“中台”这个概念自去年流行以来,至今仍然搅动着市场。期间,既有阿里、腾讯、百度、字节跳动、美团、滴滴等等头部互联网企业刮起的转型风,也有茅台延后中台签约、服装品牌CIO被开除等风波。尽管存在争议,但这不影响越来越多的企业…

java由大到小输出整数xvz_【视频+图文】Java经典基础练习题(三):输入3个整数,并将其由小到大输出...

java经典实例书店书畅想畅销书109.6元包邮(需用券)去购买 >目录https://www.cnblogs.com/Qpgshare/p/12588923.html一、视频讲解https://www.cnblogs.com/Qpgshare/p/12588923.html二、思路分析https://www.cnblogs.com/Qpgshare/p/12588923.html总结:https://ww…