如何为可变参数合并迭代器函数正确做泛型类型注解?
为任意数量迭代器的合并函数添加类型注解
方案1:基于PEP 646的类型变量元组(兼容mypy,Python 3.10+)
利用TypeVarTuple和Unpack可以实现对任意数量迭代器的精确类型标注,这是最贴合需求的方案,mypy在Python 3.10及以上版本支持该语法:
from typing import Iterator, TypeVarTuple, Unpack # 定义类型变量元组,用于存储各个迭代器的元素类型 Ts = TypeVarTuple('Ts') def merge_iterators(*its: Unpack[tuple[Iterator[Unpack[Ts]], ...]]) -> Iterator[tuple[Unpack[Ts]]]: # 示例实现:用zip合并迭代器,实际可替换为自定义合并逻辑 yield from zip(*its)
使用示例:
a: list[int] = [1, 2] b: list[str] = ['a', 'b'] c = merge_iterators(a, b) # 类型检查工具会推断c的类型为 Iterator[tuple[int, str]]
方案2:重载(兼容Python <3.10,全类型检查工具支持)
如果需要兼容更早的Python版本,可以通过函数重载覆盖常用的迭代器数量场景,虽然无法支持无限数量,但能满足绝大多数实际需求:
from typing import Iterator, overload, TypeVar T = TypeVar('T') U = TypeVar('U') V = TypeVar('V') W = TypeVar('W') # 为1到4个迭代器的场景分别定义类型注解 @overload def merge_iterators(it: Iterator[T]) -> Iterator[tuple[T]]: ... @overload def merge_iterators(it1: Iterator[T], it2: Iterator[U]) -> Iterator[tuple[T, U]]: ... @overload def merge_iterators(it1: Iterator[T], it2: Iterator[U], it3: Iterator[V]) -> Iterator[tuple[T, U, V]]: ... @overload def merge_iterators(it1: Iterator[T], it2: Iterator[U], it3: Iterator[V], it4: Iterator[W]) -> Iterator[tuple[T, U, V, W]]: ... # 兜底:超过4个迭代器时,类型推断为通用元组迭代器 @overload def merge_iterators(*its: Iterator) -> Iterator[tuple]: ... def merge_iterators(*its: Iterator) -> Iterator[tuple]: yield from zip(*its)
错误写法说明
你之前的代码错误在于直接使用*Ts作为参数和返回值的类型,PEP 646规范要求必须通过TypeVarTuple定义类型变量元组,再配合Unpack关键字来展开类型,才能让类型检查工具正确识别可变数量的类型参数。
内容的提问来源于stack exchange,提问作者Ziur Olpa
相关产品推荐
相关产品推荐

