python - 键入提示@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"
对于两者i
,j
vscode中的 Pylance 显示 type Any
。我考虑过的其他想法:
- 我想也许我可以将类型信息传递给装饰器本身(比如
@asynccontextmanager(cls=str)
,但我找不到任何例子,或者我可以传入的参数的任何描述。 async with return_str() as i: # type: str
也不行。即使是这样,我宁愿暗示函数定义,而不是每次调用。类型注释不是很干。- 我试图用和函数创建一个
AsyncContextManager
类,但没有成功。如果它有效,我会退回到它,但我更愿意让装饰器工作,因为它更简洁。__aenter()__
__aexit()__
这是我悬停该return_AsyncContextManager()
功能并显示 Pylance 弹出窗口说它返回的屏幕截图AsyncContextManager[_T]
解决方案
您必须提示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
。
这是显示类型提示转移到调用者函数的屏幕截图。
推荐阅读
- firebase - 使用 vue.js 向 firebase 发送多个值
- python - MATLAB 引擎函数的输入参数
- node.js - 生成和存储 API 密钥 - Node js
- database - 在 MATLAB 中是否有解决 Snowflake 的 TIMESTAMP_NTZ/TIMESTAMP_LTZ 的方法?
- python - Python 统计文件
- serverless-framework - webpack: configuration.entry 应该是一个非空对象
- node.js - Express API 与 SocketIO 在一起?
- linux - 在谷歌云平台开放2525端口
- powershell - 从 DSC 配置中的脚本块调用函数
- angular - 如何在 rxjs(Angular)中使用不同的参数多次重复相同的网络请求?