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

如何为collections.abc.Sequence的最小实现正确添加__getitem__方法的类型提示?

如何为collections.abc.Sequence的最小实现正确添加__getitem__方法的类型提示?

刚好我之前也踩过这个类型提示的坑,咱们一步步来理清楚问题出在哪,怎么解决:

你的核心问题是:Sequence 要求 __getitem__ 既要支持整数索引,也要支持切片(slice)操作,不同的入参类型对应不同的返回值类型——而你的原代码只考虑了整数索引的情况,所以类型检查器会报错。

1. 基础版:用Union解决类型不兼容问题

首先,key 的类型不能只写 int,必须覆盖「整数」和「切片」两种场景,所以用 Union[int, slice] 标注。返回类型也要对应两种情况:整数索引返回单个 float,切片返回子序列(Sequence[float]),所以用 Union[float, Sequence[float]]。

修正后的基础版代码如下:

from collections.abc import Sequence
from typing import override, Union

class MySeq(Sequence[float]):
    def __init__(self):
        self._data: list[float] = list()

    @override
    def __len__(self) -> int:
        return len(self._data)

    @override
    def __getitem__(self, key: Union[int, slice]) -> Union[float, Sequence[float]]:
        result = self._data[key]
        # 切片返回的是list,最好包装成自定义的MySeq实例,严格符合Sequence规范
        if isinstance(result, list):
            sub_seq = MySeq()
            sub_seq._data = result
            return sub_seq
        return result

2. 进阶版:用@overload实现精确类型推断

如果想要类型检查器能更精准地识别不同调用场景的返回类型(比如知道整数索引返回float,切片返回MySeq),可以用@overload分别标注两种情况:

from collections.abc import Sequence
from typing import override, overload, Union

class MySeq(Sequence[float]):
    def __init__(self):
        self._data: list[float] = list()

    @override
    def __len__(self) -> int:
        return len(self._data)

    @overload
    def __getitem__(self, key: int) -> float:
        ...

    @overload
    def __getitem__(self, key: slice) -> 'MySeq':
        ...

    @override
    def __getitem__(self, key: Union[int, slice]) -> Union[float, 'MySeq']:
        result = self._data[key]
        if isinstance(result, list):
            sub_seq = MySeq()
            sub_seq._data = result
            return sub_seq
        return result

用@overload之后,当你在代码里写my_seq[0],类型检查器会明确知道返回的是float;写my_seq[1:3]时,会知道返回的是MySeq,提示更精准。

为什么你的原代码会报错?

  • 关于key的警告:类型检查器知道Sequence规范要求支持切片操作,只写int不符合接口约定,所以会提示「slice不能赋值给int」。
  • 关于返回类型的警告:当传入切片时,self._data[key]返回的是list[float],但你标注的返回类型是float,类型完全不匹配,所以检查器会报错提示返回类型不兼容。

备注:内容来源于stack exchange,提问作者502E532E

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:23:01