首页 > 解决方案 > 键入提示@asynccontextmanager 的返回值的正确方法是什么?

问题描述

@asynccontextmanager为使用装饰器返回函数添加类型提示的正确方法是什么?这是我做过的两次尝试,但都失败了。

from contextlib import asynccontextmanager
from typing import AsyncContextManager


async def caller():
    async with return_str() as i:
        print(i)

    async with return_AsyncContextManager() as j:
        print(j)


@asynccontextmanager
async def return_str() -> str:
    yield "hello"


@asynccontextmanager
async def return_AsyncContextManager() -> AsyncContextManager[str]:
    yield "world"

对于两者ij vscode中的 Pylance 显示 type Any。我考虑过的其他想法:

这是我悬停该return_AsyncContextManager()功能并显示 Pylance 弹出窗口说它返回的屏幕截图AsyncContextManager[_T] 在此处输入图像描述

标签: pythonvisual-studio-codepython-asynciotype-hintingcontextmanager

解决方案


您必须提示AsyncIterator作为返回类型,如下所示:

@asynccontextmanager
async def my_acm() -> AsyncIterator[str]:
    yield "this works"


async def caller():
    async with my_acm() as val:
        print(val)

这是因为yield关键字用于创建生成器。考虑:

def a_number_generator():
    for x in range(10):  # type: int
        yield x

g = a_number_generator() # g is type Generator[int]

考虑到@asynccontextgenerator 的类型提示,这是有道理的:
asynccontextmanager(func: Callable[..., AsyncIterator[_T]]) -> Callable[..., AsyncContextManager[_T]]

这需要解析很多,但它表示asynccontextgenerator接受一个函数,该函数返回AsyncIterator并将其转换为一个返回AsyncContextManager 泛型类型的新函数_T

这是显示类型提示转移到调用者函数的屏幕截图。

在此处输入图像描述


推荐阅读