深入Asyncio(八)异步迭代器
Async Iterators: async for
除了async def和await语法外,还有一些其它的语法,本章学习异步版的for循环与迭代器,不难理解,普通迭代器是通过__iter__和__next__两个特殊方法实现的,如下例。
>>> class A:
... def __iter__(self): # 1
... self.x = 0 # 2
... return self # 3
... def __next__(self): # 4
... if self.x > 2:
... raise StopIteration
... else:
... self.x += 1
... return self.x
>>> for i in A():
... print(i)
...
1
2
3
迭代器必须支持__iter__方法;
值初始化;
返回一个可迭代对象,这个对象可以执行__next__方法,这里A本身就实现了__next__方法,所以返回它本身即可;
在每次迭代时调用。
将__next__()方法声明为异步函数,要允许await某些IO操作,除开命名的差别外,几乎是相同的定义,PEP 492中规范说明了如何实现一个异步迭代器:
1. 实现__aiter__()方法(不需要用async def);
2. __aiter__()方法必须返回一个支持__anext__()方法的对象;
3. __anext__()必须返回迭代器的每个值,并在结束迭代时抛出StopAsyncIteration异常。
举个例子,比如Redis的key对应的value是一个很大的集合,想迭代这些key的value会出现严重的网络IO,异步迭代器可以这样实现:
import asyncio
from aioredis import create_redis
async def main(): # 1
redis = await create_redis(('localhost', 6379)) # 2
keys = ['America', 'Africa', 'Europe', 'Asia'] # 3
async for value in OneAtTime(redis, keys): # 4
await process(value) # 5
class OneAtTime:
def __init__(self, redis, keys): # 6
self.redis = redis
self.keys = keys
def __aiter__(self): # 7
self.ikeys = iter(self.keys)
return self
async def __anext__(self): # 8
try:
k = next(self.ikeys) # 9
except StopIteration: # 10
raise StopAsyncIteration
value = await redis.get(k) # 11
return value
asyncio.get_event_loop().run_until_complete(main())
主程序入口,用于在loop.run_until_complete()方法中调用;
使用aioredis库获取异步连接;
假设每个key对应的value实例非常大;
使用async for循环,关键点是这里的迭代器可以在等待数据时切换任务;
在得到返回值后用协程去处理这个值,假设这个函数也是IO绑定的;
用一个实例来存储redis连接和keys表;
像普通迭代器一样,初始化一些值,这里我们创建一个迭代器作值,由于这个类也重载了__anext__方法,所以直接返回自身;
__anext__方法用async def声明;迭代这个普通的迭代器;
处理普通异常并重新抛出一个异步异常;
这个调用是网络IO,因此用await切换它。
通过以上实现,将可以用一个异步for循环来迭代一些处理网络IO的异步迭代器,好处是可以只用一个事件loop就能处理大量的数据。
深入Asyncio(八)异步迭代器的更多相关文章
- 一文说通C#中的异步迭代器
今天来写写C#中的异步迭代器 - 机制.概念和一些好用的特性 迭代器的概念 迭代器的概念在C#中出现的比较早,很多人可能已经比较熟悉了. 通常迭代器会用在一些特定的场景中. 举个例子:有一个for ...
- C# 8 中的异步迭代器 IAsyncEnumerable<T> 解析
异步编程已经流行很多年了,.NET 引入的 async 和 await 关键词让异步编程更具有可读性,但有一个遗憾,在 C# 8 之前都不能使用异步的方式处理数据流,直到 C# 8 引入的 IAsyn ...
- 在Python中使用asyncio进行异步编程
对于来自JavaScript编码者来说,异步编程不是什么新东西,但对于Python开发者来说,async函数和future(类似JS的promise)可不是那么容易能理解的. Concurrency ...
- Python使用asyncio+aiohttp异步爬取猫眼电影专业版
asyncio是从pytohn3.4开始添加到标准库中的一个强大的异步并发库,可以很好地解决python中高并发的问题,入门学习可以参考官方文档 并发访问能极大的提高爬虫的性能,但是requests访 ...
- asyncio之异步上下文管理器
异步上下文管理器 前面文章我们提到了上下文管理器,但是这个上下文管理器只适用于同步代码,不能用于异步代码(async def形式),不过不用担心今天我们就来讨论在异步中如何使用上下文管理器. 特别提醒 ...
- python基础(八)-迭代器与生成器
一.迭代器 li=[1,2,3] f=li.__iter__() print(f) print(f.__next__()) print(f.__next__()) print(f.__next__() ...
- python基础(八)生成器,迭代器,装饰器,递归
生成器 在函数中使用yield关键字就会将一个普通的函数变成一个生成器(generator),普通的函数只能使用return来退出函数,而不执行return之后的代码.而生成器可以使用调用一个next ...
- Python复习笔记(八)迭代器和生成器和协程
1. 迭代器 1.1 可迭代对象 判断xxx_obj是否可以迭代 在第1步成立的前提下,调用 iter 函数得到 xxx_obj 对象的 __iter__ 方法的返回值 __iter__ 方法的返回值 ...
- JDK7新特性<八>异步io/AIO
概述 JDK7引入了Asynchronous I/O.I/O编程中,常用到两种模式:Reactor 和 Proactor.Reactor就是Java的NIO.当有事件触发时,我们得到通知,进行相应的处 ...
随机推荐
- 用正则表达式把页面中的px全部替换成rem
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 【Visual Studio】“rc.exe”已退出,代码为 5 ("rc.exe" exited with code 5.)
[解决方案]找到 rc.exe 所在目录,然后 方法1:添加该目录到 VC++ Directories --> Executable Directories中 方法2:添加到系统变量中的Path ...
- 转 C++拷贝构造函数详解
C++拷贝构造函数详解 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a = 100; int b = a; 而类对象与普通对象不同,类对象内部结构一 ...
- EBImage - - 给图片增加字符
EBImage中文文档 英文版出处:http://www.bioconductor.org/packages/release/bioc/vignettes/EBImage/inst/doc/EBIma ...
- 《30天学习30种新技术》-Day 15:Meteor —— 从零开始创建一个 Web 应用
目录:https://segmentfault.com/a/1190000000349384 原文: https://segmentfault.com/a/1190000000361440 到目前为止 ...
- PHP操作MongoDB(增删改查)
MongoDB的PHP驱动提供了一些核心类来操作MongoDB,总的来说MongoDB命令行中有的功能,它都可以实现,而且参数的格式基本相似.PHP7以前的版本和PHP7之后的版本对MongoDB的操 ...
- HDU 2034 人见人爱A-B【STL/set】
人见人爱A-B Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- HashMap之equals和hashCode小陷阱
先以一段代码开始这篇blog. 01 public class Name { 02 03 private String first; //first name 04 private Str ...
- https://www.cnblogs.com/netoxi/p/7258895.html
https://www.cnblogs.com/netoxi/p/7258895.html 应用服务和数据服务分离 需求/解决问题 随着网站业务的发展,越来越多的用户访问导致性能越来越差,越来越多的数 ...
- EasyMvc入门教程-基本控件说明(4)折叠面板
折叠面板一般出现在管理后台,大家用的OutLook里就是用了折叠面板,样子大概是这样的: 把其中的内容替换成图标按钮,是不是就是我们常见的样子了?:)那么如何实现呢?请看例子: @{ var data ...