【问题标题】:python: iterate over either a list or an async generatorpython:迭代列表或异步生成器
【发布时间】:2021-06-08 11:17:26
【问题描述】:

自从在 python 中引入了迭代器,你总是可以不关心你是在处理迭代器还是列表:

from random import random

def gen_list():
    print('gen')
    for i in range(10):
        yield i

def return_list():
    print('return')
    return [i for i in range(10)]


if random() > 0.5:
    x = gen_list()
else:
    x = return_list()

for i in x:
    pass

PEP 492 引入了 asynchronous iteratorsasync for 语法。我看不到为异步迭代器的使用者添加语法的新负担的任何理由。

在我的代码中,我有时处理一个列表(来自缓存),有时处理一个异步生成器:

import asyncio
from random import random

def is_small_and_in_cache():
    if random() > 0.5:
        print('in fake cache')
        return [i for i in range(10)]

async def get_progressively():
    print('gen')
    for i in range(10):
        # e.g. an await here
        await asyncio.sleep(0.1)
        yield i

async def main():
    x = is_small_and_in_cache()
    if x is None:
        x = get_progressively()

    async for i in x:
        pass

asyncio.run(main())

但上述失败(一半时间)TypeError: 'async for' requires an object with __aiter__ method, got list

主要问题:如何写这个以便我们可以处理任何一个?我应该尝试将列表转换为虚拟异步生成器,还是包装异步生成器以生成列表?

支线任务:是否有任何建议可以摆脱(对我来说显然是非pythonic)async for 构造,即为什么常规的for 循环不能处理异步生成器? Python3x 在可用性方面已经失去了方向??

【问题讨论】:

    标签: python asynchronous python-asyncio


    【解决方案1】:

    语法的存在是为了警告你,你的“循环”实际上可能包括暂停你的整个调用,允许其他代码运行,这样你就知道在顶部有适当的数据处于一致的状态每次迭代。它不会去任何地方。

    当然,协程必须暂停,您可以使用它来包装任何可迭代的琐碎:

    async def desync(it):
      for x in it: yield x
    

    这比相反的数字更普遍有用——它仍然是异步的,因为它必须——聚集到一个列表中:

    async def gather(ai):
      ret=[]
      async for x in ai: ret.append(x)
      return ret
    

    因为它允许在完全异步的情况下进行适当的交错。

    【讨论】:

    • hmmm,虽然它是学术性的,for i in await x: 会更好地理解这个想法,因为放弃控制的不是循环,而是生成器。这也将更好地反映现有 async 函数系统的 caller=>await/callee=>async。
    • @EoghanM: for i in await x: 已经意味着一些东西:x 是一些可等待的(例如,一个暂停的异步生成器),它提供了一个完整的(同步的)可迭代的一口气。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 2017-11-15
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    相关资源
    最近更新 更多