定义不可变列表类型时遇mypy错误:Tuple类型不兼容
解决mypy对Tuple[str]类型NewType的类型不兼容错误
问题场景
使用NewType定义基于元组的不可变类型时,mypy抛出类型不兼容错误。相关代码及错误信息如下:
原代码
import sys from re import split from typing import Tuple, List, NewType tokens = split("(\\d+\\.\\d+)", sys.argv[1]) # 改用Tuple后报错 Tokens = NewType("Tokens", Tuple[str]) print(Tokens(tuple(tokens)))
mypy错误信息
> mypy main.py main.py:13: error: Argument 1 to "Tokens" has incompatible type "Tuple[Union[str, Any], ...]"; expected "Tuple[str]" Found 1 error in 1 file (checked 1 source file)
解决方案
1. 修正元组类型定义
Tuple[str]表示仅包含单个字符串元素的固定长度元组,但tuple(tokens)生成的是包含多个字符串的变长元组,正确类型应为Tuple[str, ...]。修改NewType的底层类型:
Tokens = NewType("Tokens", Tuple[str, ...])
2. 明确split返回值的类型注解
re.split的默认类型推断不够精确,mypy无法确定返回的列表元素全为str,需给tokens添加明确的类型标注:
tokens: List[str] = split("(\\d+\\.\\d+)", sys.argv[1])
最终修正代码
import sys from re import split from typing import Tuple, List, NewType tokens: List[str] = split("(\\d+\\.\\d+)", sys.argv[1]) Tokens = NewType("Tokens", Tuple[str, ...]) print(Tokens(tuple(tokens)))
原因说明
- 使用
List[str]时正常,是因为List[str]本身就是变长列表类型,与split返回的列表类型天然兼容。 - 原错误中,
Tuple[str]的固定长度定义与实际生成的变长元组类型不匹配,加上split返回值的类型推断模糊,导致mypy报错。
内容的提问来源于stack exchange,提问作者OrenIshShalom
相关产品推荐
相关产品推荐

