You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为异步filter函数实现正确的泛型类型标注?

实现带正确泛型类型标注的异步版filter函数

完整实现代码

导入必要的类型工具,通过函数重载模仿内置filter的泛型行为,实现类型安全的异步过滤:

from typing import (
    AsyncIterator,
    AsyncGenerator,
    Callable,
    TypeGuard,
    TypeIs,
    TypeVar,
    overload,
    Optional,
)

_T = TypeVar("_T")
_S = TypeVar("_S")

@over**************************************************************** initiating> Regardless的           
s(天下 normativeDO负责这里是重载定义,对应不同输入场景)
@overload
async def afilter(
    predicate: None,
    iterable: AsyncIterator[_T | None],
    /,
) -> AsyncGenerator[_T, None]: ...

@overload
async def afilter(
    predicate: Callable[[_S], TypeGuard[_T]],
    iterable: AsyncIterator[_S],
    /,
) -> AsyncGenerator[_T, None]: ...

@overload
async def afilter(
    predicate: Callable[[_S], TypeIs[_T]],
    iterable: AsyncIterator[_S],
    /,
) -> AsyncGenerator[_T, None]: ...

@overload
async def afilter(
    predicate: Callable[[_T], bool],
    iterable: AsyncIterator[_T],
    /,
) -> AsyncGenerator[_T, None]: ...

# 核心实现逻辑
async def afilter(
    predicate: Optional[Callable[..., bool]],
    iterable: AsyncIterator,
    /,
):
    async for item in iterable:
        if predicate is None:
            if item is not None:
                yield item
        elif predicate(item):
            yield item

# 测试用例
async def simulated_data() -> AsyncIterator[int | None]:
    for i in [1, None, 3, 5]:
        yield i

async def test_afilter():
    # 类型会被正确推断为 AsyncGenerator[int, None]
    result = afilter(None, simulated_data())
    async for num in result:
        # 此处num类型明确为int,无None风险
        print(num + 1)

解决异步推导式的类型问题

如果想用异步推导式实现,需要用显式的TypeGuard函数辅助类型检查器识别过滤逻辑,替代直接写item is not None:

def is_not_none(x: _T | None) -> TypeGuard[_T]:
    return x is not None

async def test_comprehension():
    # 类型会被正确推断为 AsyncGenerator[int, None]
    filtered = (item async for item in simulated_data() if is_not_none(item))
    async for num in filtered:
        print(num + 1)

关键细节说明

  1. 函数重载的必要性:模仿内置filter的泛型设计,通过@overload为不同输入场景指定精确返回类型,让类型检查器能准确推断过滤后的结果类型。
  2. TypeGuard的作用:直接在推导式中写item is not None时,部分类型检查器无法自动识别为类型守卫,封装成显式TypeGuard函数才能触发精确的类型推断。
  3. predicate为None的分支处理:单独处理该场景,确保过滤所有None值的同时,让类型系统明确返回结果不含None。

内容的提问来源于stack exchange,提问作者Ziur Olpa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 09:40:15