如何告知mypy:集合推导式中re.search结果不含None值?
解决集合推导式中mypy对re.search返回Optional的报错问题
你的问题出在断言的方向错了:你断言matched_policies里没有None,但mypy报错的是re.search(r"p\d{6}", matched_policy)可能返回None,和matched_policy本身是否为None完全无关。
下面是几种用集合推导式解决的优雅方案:
方案1:海象运算符+条件过滤
利用海象运算符先捕获匹配结果,再用条件过滤告诉mypy结果非None。因为你确定所有元素都能匹配,过滤不会丢弃任何数据,但mypy会自动识别match在这里不可能是None:
return { match.group(0) for matched_policy in matched_policies if (match := re.search(r"p\d{6}", matched_policy)) is not None }
这个方案还能顺便处理意外情况——万一真有不匹配的元素,会自动过滤掉,避免运行时抛出AttributeError。
方案2:封装辅助函数+断言
把匹配逻辑抽成单独函数,在函数内部加断言确认匹配结果非None,mypy会信任这个断言的类型提示:
import re def get_policy_id(policy_str: str) -> str: match_result = re.search(r"p\d{6}", policy_str) assert match_result is not None, "输入的策略字符串必须包含格式为pxxxxxx的ID" return match_result.group(0) # 集合推导式里直接调用函数 return {get_policy_id(policy) for policy in matched_policies}
这种方式逻辑更清晰,还能复用匹配逻辑,断言也能在运行时做检查,防止后续代码改动导致的意外问题。
方案3:强制类型转换(typing.cast)
如果你完全确定不会出现匹配失败的情况,可以用cast直接告诉mypy,re.search的结果不是Optional类型:
from typing import cast, Match return { cast(Match[str], re.search(r"p\d{6}", matched_policy)).group(0) for matched_policy in matched_policies }
注意:这个方法没有运行时检查,一旦后续出现不匹配的元素,会直接抛出AttributeError,只适合你能100%保证匹配成功的场景。
内容的提问来源于stack exchange,提问作者jamiet
相关产品推荐
相关产品推荐

