如何定义返回空AsyncIterable的类型安全异步函数?
如何定义返回空AsyncIterable的默认函数?
我需要定义一个返回具体类型空AsyncIterable的函数,作为基类的默认实现——派生类可按需重写它,但默认行为是返回无迭代项。但这个具体类型没有合适的默认值,代码必须通过mypy类型检查,理想情况下也能通过pylint检查。
无效的尝试
以下几种写法都无法满足要求:
- 直接使用
pass或空return:
async def nope() -> AsyncIterable[int]: pass # error: Missing return statement [empty-body] # 普通def函数也会报同样错误
async def nope() -> AsyncIterable[int]: return # error: Return value expected [return-value] # 普通def函数也会报同样错误
- 错误使用
yield from:
async def nope() -> AsyncIterable[int]: yield from () # error: "yield from" in async function
def nope() -> AsyncIterable[int]: yield from () # error: The return type of a generator function should be "Generator" or one of its supertypes [misc]
- 带常量条件的
yield(会触发pylint警告):
async def nope() -> AsyncIterable[int]: if False: yield 1 # W0125: Using a conditional statement with a constant value (using-constant-test)
可行的实现方式
方法1:异步空生成器(推荐)
定义一个不产生任何值的异步生成器函数,mypy会正确识别其返回类型,pylint也不会报错:
from typing import AsyncIterable, AsyncGenerator async def empty_async_iterable() -> AsyncIterable[int]: pass
或者更严谨地标注为AsyncGenerator(明确无发送值):
async def empty_async_iterable() -> AsyncGenerator[int, None]: pass
异步生成器函数即使没有yield语句,也会返回一个空的异步迭代器,完全符合需求。
方法2:自定义空异步迭代器
如果需要更显式的实现,可以手动创建一个空的异步迭代器类,返回其实例:
from typing import AsyncIterable from collections.abc import AsyncIterator class EmptyAsyncIterator(AsyncIterator[int]): async def __anext__(self) -> int: raise StopAsyncIteration() def empty_async_iterable() -> AsyncIterable[int]: return EmptyAsyncIterator()
这种方式适合需要复用空迭代器实例的场景。
内容的提问来源于stack exchange,提问作者Koterpillar
相关产品推荐
相关产品推荐

