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识别类的可解包属性,不用调整原有业务代码:
- 新增
foo.pyi文件(和你定义Foo的py文件同名) - 写入以下内容:
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
相关产品推荐
相关产品推荐

