【问题标题】:What is the proper way to type hint the return value of an @asynccontextmanager?键入提示@asynccontextmanager 的返回值的正确方法是什么?
【发布时间】:2020-11-17 08:53:49
【问题描述】:

使用@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 Pylance 在 vscode 中显示类型 Any。我考虑过的其他想法:

  • 我想也许我可以将类型信息传递给装饰器本身(例如 @asynccontextmanager(cls=str),但我找不到任何示例,或者我可以传入的 args 的任何描述。
  • async with return_str() as i: # type: str 也不起作用。即使是这样,我宁愿暗示函数定义,而不是每次调用。类型 cmets 不是很干燥。
  • 我尝试使用__aenter()____aexit()__ 函数创建AsyncContextManager 类,但没有成功。如果它有效,我会退回到它,但我更愿意让装饰器工作,因为它更简洁。

这是我悬停在 return_AsyncContextManager() 函数上的屏幕截图,并显示 Pylance 弹出窗口说它返回 AsyncContextManager[_T]

【问题讨论】:

  • 去掉asynccontextmanager调用中的括号,它的参数应该是函数本身,而不是类型
  • 是的,我尝试了很多不同的迭代。我不小心粘贴了一些愚蠢的尝试。即使使用标准的@asynccontextmanager(无括号)装饰器,它也表现出相同的Any 类型推断。我已更新问题以显示标准代码。

标签: python visual-studio-code python-asyncio type-hinting contextmanager


【解决方案1】:

你必须提示 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]

考虑到type hints for @asynccontextgenerator:
asynccontextmanager(func: Callable[..., AsyncIterator[_T]]) -> Callable[..., AsyncContextManager[_T]]

,这是有道理的

要解析的内容很多,但它表示 asynccontextgenerator 接受一个返回 AsyncIterator 的函数并将其转换为一个返回 AsyncContextManager 的新函数。泛型类型 _T 也被保留。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 2016-11-05
    • 1970-01-01
    • 2020-03-26
    相关资源
    最近更新 更多