解决mypy赋值类型不兼容错误:list[str]|list[Path]与list[Path]
解决mypy类型不兼容错误
错误原因
报错行found_files = sort_nicely(found_files)中,found_files的实际类型是list[Path](文件查找阶段已经把所有结果转成了Path对象),但sort_nicely的返回类型标注为list[str] | list[Path],mypy无法确定排序后的结果一定是list[Path],因此抛出类型不兼容的赋值错误。
解决方案
方案1:用泛型让sort_nicely类型更精确
这是最规范的做法,让函数根据输入类型返回对应类型,mypy能自动推断正确结果:
修改代码如下,添加泛型相关导入和注解:
import re import glob from pathlib import Path from typing import Sequence, TypeVar, Generic # 定义类型变量,限定为str或Path T = TypeVar('T', str, Path) def find_files(files: str | Sequence[str], sort: bool = True) -> list[Path]: """Find files based on shell-style wildcards. files = '/path/to/all/*.csv' files = [ '/path/to/all/*.csv', '/and/to/all/*.xlsx' ] """ # Convert to list if input is a str. files = [files] if isinstance(files, str) else files # Find files. found_files = [Path(fglob).resolve() for f in files for fglob in glob.glob(f, recursive=True)] # Make sure no duplicates exist. found_files = [*set(found_files)] if sort: found_files = sort_nicely(found_files) # mypy不再报错 return found_files def sort_nicely(lst: Sequence[T]) -> list[T]: """Perform natural human sort. sort_nicely(['P1', 'P10', 'P2']) == ['P1', 'P2', 'P10'] """ def convert(text: str) -> str | int: return int(text) if text.isdigit() else text def alpha_key(item: str | Path) -> list[str | int]: return [convert(c) for c in re.split('([0-9]+)', str(item))] return sorted(lst, key=alpha_key)
同时修正了find_files的返回类型——因为所有查找结果都转成了Path,所以返回类型应该是list[Path]而非联合类型,这也能减少类型歧义。
方案2:类型断言(快速临时解决)
如果不想修改泛型,也可以用类型断言明确告诉mypy返回的是list[Path]:
from typing import cast # 在赋值时添加断言 if sort: found_files = cast(list[Path], sort_nicely(found_files))
或者直接忽略该错误(不推荐,会掩盖潜在问题):
if sort: found_files = sort_nicely(found_files) # type: ignore
方案3:修正sort_nicely的返回类型(针对当前场景)
因为在find_files中传入的是list[Path],可以把sort_nicely的返回类型改为list[Path],但这样函数的通用性会下降,仅适合当前场景:
def sort_nicely(lst: Sequence[str] | Sequence[Path]) -> list[Path]: # ... 原有逻辑不变
内容的提问来源于stack exchange,提问作者Simon1
相关产品推荐
相关产品推荐

