Python异步生成器类型设置

h6my8fg2  于 2023-03-11  发布在  Python
关注(0)|答案(1)|浏览(159)

下面是两个不同类型的函数。代码按预期运行。PyCharm和mypy也没有显示警告或错误。
但VS代码显示gen1()函数警报:
异步生成器函数的返回类型必须为“AsyncGenerator”或“AsyncIterable”类型(reportGeneralTypeIssues)
所以问题是:

  1. gen1()定义中的“可选”类型是否多余?(* 我认为是多余的,因为除了AsyncGenerator作为返回值之外,没有其他方法可以接收任何内容 *)
    1.使用异步类型VS代码中的Pylance是否有问题?
    讨论的代码:
import asyncio
from typing import AsyncGenerator, Optional

async def gen1() -> Optional[AsyncGenerator[str, None]]:
    while True:
        return
    yield "t"

async def gen2() -> AsyncGenerator[str, None]:
    while True:
        return
    yield "t"

async def main():
    print(f"{type(gen1())=}")
    print(f"{type(gen2())=}")
    async for d in gen1():
        print(d)
    
asyncio.run(main())

顺便说一句,在一些流行的软件包中使用了类似gen1的类型。https://github.com/pyrogram/pyrogram/blob/master/pyrogram/methods/chats/get_chat_members.py

async def get_chat_members(
        self: "pyrogram.Client",
        chat_id: Union[int, str],
        query: str = "",
        limit: int = 0,
        filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.SEARCH
    ) -> Optional[AsyncGenerator["types.ChatMember", None]]:
56lgkhnf

56lgkhnf1#

您可以安全地从该代码中删除Optional
在这种情况下,返回AsyncGenerator的不是您编写的任何代码:从函数被定义为async并在其主体中有一个yield开始,Python语言本身将使其成为Async Generator Function,其唯一可能的返回类型(在语言中硬编码)是AsyncGenerator --不管代码是如何组织的,或者当def块中的代码实际运行时实际执行什么。
它表示这个函数适合用在async for语句中--或者用anext和/或sendthrow手动驱动,Python本身在调用这个函数时不会返回None:相反,到空return的短路仅指示生成器本身在迭代时将为空。据我所知,没有现有的类型标记来指示生成器将为空。
就注解而言,这也是无关紧要的,但事实上,一个被标记为“将始终为空”的Generator可以安全地被丢弃,而不需要尝试对其进行迭代:检查这类逻辑超出了静态类型注解必须做的事情(尽管有些检查器很好,可以做到这一点--这与“未使用的变量”属于同一类别)。

相关问题