Python自定义类解包时如何实现类型检查器自动类型推导?
让自定义类解包时支持精确类型推导
当使用元组解包时,mypy和pyright能准确推导每个变量的类型,但自定义类仅实现__iter__时,类型检查器只能给出Any或联合类型,无法得到像元组那样的精确结果。要解决这个问题,可以通过以下几种方法实现:
方法一:实现Sequence协议
让类继承Sequence并正确标注__getitem__和__len__的类型,类型检查器会将其识别为固定长度的序列,从而正确推导解包后的变量类型:
from typing import Sequence, overload, Iterator class T(Sequence[int | str]): def __init__(self): self.a = 33 self.b = "hello" @overload def __getitem__(self, index: int) -> int | str: ... @overload def __getitem__(self, index: slice) -> list[int | str]: ... def __getitem__(self, index): items = [self.a, self.b] return items[index] def __len__(self) -> int: return 2 def __iter__(self) -> Iterator[int | str]: return iter((self.a, self.b)) t = T() a, b = t # mypy和pyright均能推导a为int,b为str
方法二:Python 3.11+ 使用__tuple__方法
Python 3.11引入了__tuple__方法,通过实现该方法并标注返回的精确元组类型,类型检查器可以直接根据返回类型推导解包后的变量类型:
from typing import Tuple class T: def __init__(self): self.a = 33 self.b = "hello" def __tuple__(self) -> Tuple[int, str]: return (self.a, self.b) def __iter__(self): return iter(self.__tuple__()) t = T() a, b = t # 类型检查器可正确推导a为int,b为str
原代码问题说明
原代码中__iter__仅返回一个包含int和str的迭代器,类型检查器无法从迭代器中推断出元素的固定数量和顺序对应的精确类型。而元组属于固定长度的序列类型,类型检查器有专门的逻辑处理其解包的类型推导,因此需要通过上述方法让自定义类向类型检查器传递足够的类型信息。
内容的提问来源于stack exchange,提问作者Holt
相关产品推荐
相关产品推荐

