Python 'AsyncIterable[T]`和'Iterable[Waitiable[T]]]之间的区别是什么?

Python 'AsyncIterable[T]`和'Iterable[Waitiable[T]]]之间的区别是什么?,python,asynchronous,async-await,generator,python-asyncio,Python,Asynchronous,Async Await,Generator,Python Asyncio,执行以下两个功能: import asyncio def a(): for index in range(2): # Capture `index` as `local_index` in case awaiting is postponed. async def next_index(local_index=index): # Simulate network request. await asyncio

执行以下两个功能:

import asyncio

def a():
    for index in range(2):
        # Capture `index` as `local_index` in case awaiting is postponed.
        async def next_index(local_index=index):
            # Simulate network request.
            await asyncio.sleep(0)

            return local_index

        yield next_index()

async def b():
    for index in range(2):
        # Simulate network request.
        await asyncio.sleep(0)

        yield index
a
返回一个
Iterable[waitiable[int]]
b
返回一个
异步可编[int]
。两种方法的迭代都可以这样做:

async def main():
    for index in a():
        print(await index)

    async for index in b():
        print(index)

asyncio.run(main())
输出:

0
1
0
1
上面示例中的关键是,我能够在没有外部
async
的情况下生成
Awaitable
s,因为内部函数是
async

  • 在功能方面,
    AsyncIterable[T]
    是否有什么比
    Iterable[waitiable[T]]
    更好的地方
  • 我还有一个非常相关的问题。发件人:

    异步迭代器对象必须实现anext方法 (或者,如果使用CPython C API定义,则tp_作为\u async.am\u下一个插槽) 返回一个等待的消息

  • 由于不需要外部
    异步
    来生成
    可等待的
    s,那么
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

  • 这可能是我遗漏了一些东西的地方,但从我目前的理解来看,异步协议和
    StopAsyncIteration
    似乎可以使用同步协议和
    StopIteration
    (当然不那么简洁)来模仿它们。

    您遗漏的一个大问题是如何处理循环结束

    异步迭代器的
    \uuuu anext\uuuu
    返回一个可等待的值,该值可以挂起、使用值提升
    StopIteration
    以生成下一个元素,或者提升
    StopAsyncIteration
    以发出循环结束的信号。(政治公众人物说“要停止迭代,必须引发StopAsyncIteration异常。”,但StopAsyncIteration异常实际上是在等待可等待的对象时发生的,而不是在调用
    \UuAsyncIteration\UuncE>时同步发生的。)

    相反,如果您尝试使用可等待的元素使常规iterable,那么迭代器的
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    需要启动
    停止迭代来结束循环

    这意味着,
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>在知道是否会有另一个元素之前不能返回<代码>\uuuuuuuuuuuuuuuuuuuuuu下一步\uuuuuuuu
    是同步的,所以当它计算出这一点时,控件不能返回到事件循环。这意味着当所有其他工作暂停时,您可能会浪费大量时间同步等待网络流量或其他信息

    您可以通过更多的手动处理来解决这个问题,但这在两端都会变得非常棘手,尤其是迭代器端,您需要某种类似于StopAsyncIteration的方法来消除“下一个元素”与“循环完成”之间的歧义