Python使用TypeVar标注生成器遇类型不兼容,求正确类型标注方法
解决带最后元素标识生成器的mypy类型错误
你的代码中mypy报错的核心原因是:chain(sequence, [_MISSING])将原序列元素(类型_T1)与_MISSING(类型object)合并后,pairwise返回的元组类型被推断为tuple[object, object],导致current_item的类型与生成器标注的_T1不兼容。
最优解决方案:重写逻辑避免类型混淆
直接通过迭代器遍历序列,逐个判断元素是否为最后一个,无需引入额外标记对象,同时保证类型完全匹配:
from collections.abc import Generator, Iterable from typing import TypeVar _T1 = TypeVar('_T1') def annotated_last(sequence: Iterable[_T1]) -> Generator[tuple[_T1, bool], None, None]: it = iter(sequence) try: prev_item = next(it) except StopIteration: # 处理空序列的情况 return # 遍历剩余元素,返回非最后一个元素 for item in it: yield prev_item, False prev_item = item # 返回最后一个元素,标记为True yield prev_item, True
保留原逻辑的修复方式
如果坚持使用pairwise和chain的实现,可以通过类型断言明确current_item的类型,让mypy认可类型兼容性:
from collections.abc import Generator, Iterable from itertools import chain, tee from typing import TypeVar, cast _T1 = TypeVar('_T1') _MISSING = object() def pairwise(iterable: Iterable[_T1]) -> Iterable[tuple[_T1, _T1]]: a, b = tee(iterable) next(b, None) return zip(a, b) def annotated_last(sequence: Iterable[_T1]) -> Generator[tuple[_T1, bool], None, None]: for current_item, next_item in pairwise(chain(sequence, [_MISSING])): is_last = next_item is _MISSING # 类型断言:current_item一定是原序列的元素,不会是_MISSING yield cast(_T1, current_item), is_last
这种方式依赖类型断言,需确保逻辑上current_item绝不会是_MISSING(仅next_item可能为_MISSING),因此断言是安全的。
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

