python - 使用 AsyncGenerator 或 AsyncIterator 进行打字的区别?

问题描述 投票:0回答:2

我创建了一个完全类型化的不和谐异步库。 我有一个从 aiohttp get 请求创建对象的方法,如下例所示:

async def get_bans(self):
    """|coro|
    Fetches all the bans in the guild.
    """
    data = await self._http.get(f"guilds/{self.id}/bans")
    for ban_data in data:
        yield Ban.from_dict(construct_client_dict(self._client, ban_data))

我想知道这个代码片段的返回类型以及它是否应该是

AsyncGenerator[Ban, None]
AsyncIterator[Ban, None]
。老实说,我一直在寻找一些信息,我可以找到任何能让我对这个主题有清晰想法的信息。

python asynchronous iterator generator python-typing
2个回答
5
投票

官方文档将AsyncIterator描述为:

...提供

__aiter__
__anext__
方法 ...

AsyncGenerator 从文档引向PEP525

...生成器是包含一个或多个

yield
表达式的任何函数...

调用异步生成器函数的结果是一个异步生成器对象...

异步生成器定义了这两种方法(

__aiter__
__anext__

所以我认为,由于函数中的

yield
,最好使用
AsyncGenerator


0
投票

我是从语义的角度来看它。

AsyncGenerator
AsyncIterator
的继承者。来自 Python 3.12 来源:

class AsyncGenerator(AsyncIterator[_YieldT_co], Generic[_YieldT_co, _SendT_contra]): ...

进行简短检查以确认这一点:

>>> async def gen_or_iter():
...   yield 1
... 
>>> x = gen_or_iter()
>>> isinstance(x, typing.AsyncGenerator)
True
>>> isinstance(x, typing.AsyncIterator)
True
>>> 

在我看来,如果使用

asend()
不适用于具体的生成器实现,换句话说,该函数不使用像
x = yield
这样的表达式,并且表现为纯迭代器,则
AsyncGenerator[T, None]
在语义上与
AsyncIterator[T]
相同.

因此,尽管

AsyncGenerator[T, None]
是一个更精确的声明,但在纯迭代器行为的情况下,使用
AsyncIterator[T]
也可能是正确且合理的。

© www.soinside.com 2019 - 2024. All rights reserved.