You need to enable JavaScript to run this app. mypy能否识别实现__getitem__的自定义类的解包操作?
优惠活动
大模型
产品
解决方案
定价
更多

mypy能否识别实现__getitem__的自定义类的解包操作?

问题原因

mypy的类型系统不会默认将仅实现__getitem__的类识别为可解包对象,Python运行时的解包兼容逻辑(基于__getitem__顺序抛出IndexError实现)没有被mypy默认纳入校验规则,只有显式满足序列协议或者迭代协议的类,mypy才会认可其支持*解包操作。

解决方案

方案1:修改运行时代码(最推荐)

给你的Foo类补充__len__方法,同时继承typing.Sequence,完全符合Python序列协议规范,mypy会天然识别该类实例可解包:

from typing import Any, Sequence

class Foo(Sequence[Any]):
    def __getitem__(self, idx: int) -> Any:
        if idx == 0:
            return 1
        if idx == 1:
            return "bye"
        else:
            raise IndexError
    
    def __len__(self) -> int:
        # 按你实际的元素数量返回即可
        return 2


f = Foo()
t = ("hello", *f)

print(t)  # 输出 ("hello", 1, "bye")

这个方案不需要修改任何调用侧代码,也不需要加错误抑制注释,同时让你的类实现更规范。

方案2:使用stub文件(无侵入运行时代码)

如果你不想修改原有运行时代码,可以新增同名.pyi类型桩文件,让mypy识别类的可解包属性,不用调整原有业务代码:

  1. 新增foo.pyi文件(和你定义Foo的py文件同名)
  2. 写入以下内容:
from typing import Any, Sequence

class Foo(Sequence[Any]):
    def __getitem__(self, idx: int) -> Any: ...
    def __len__(self) -> int: ...

mypy检查时会优先读取.pyi文件的类型定义,不会校验运行时是否真的实现了__len__,运行时逻辑完全不受影响。

内容的提问来源于stack exchange,提问作者Michael Anderson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 22:57:02