为何mypy认为可选列表的包含检查结果不总是布尔类型?
为何mypy不认为
a and test in a这类表达式的类型是bool? 我写了这段代码:
a: list[str] | None = None b: list[str] | None = None def f(test: str) -> bool: flag: bool = not a and not b flag2: bool = a and test in a flag3: bool = b and test not in b return flag or flag2 or flag3
原本以为flag2和flag3的类型肯定是布尔值,但mypy却提示它们的类型是list[str] | None | bool的联合类型。改成flag2: bool = a is not None and test in a后,类型提示就正常了。既然这些都是条件判断表达式,为什么必须用is not None才能让mypy正确识别类型?
核心原因:Python逻辑运算符and/or的返回规则
Python里的and和or并不是统一返回布尔值,而是返回参与运算的其中一个操作数,遵循短路求值逻辑:
- 对于
x and y:如果x在布尔判断中为假,直接返回x;否则返回y - 对于
x or y:如果x在布尔判断中为真,直接返回x;否则返回y
放到你的代码里分析:
- 当
a是None时,a and test in a会直接返回None(None属于布尔假值) - 当
a是空列表[]时,a and test in a会直接返回空列表(空列表也属于布尔假值) - 当
a是非空列表时,才会返回test in a的布尔结果(True/False)
mypy严格遵循Python的实际运行语义做类型推断,所以它会把这三种可能的返回值类型合并,得出list[str] | None | bool的联合类型,和你声明的bool类型不匹配。
为什么a is not None and test in a能解决问题?
is not None是纯布尔判断:无论a是什么值,a is not None的结果都是严格的布尔值(True/False)- 触发类型窄化:当
a is not None为True时,mypy会自动推断此时a的类型是list[str](排除了None的可能),后续的test in a返回布尔值;当a is not None为False时,整个表达式返回False(布尔值)。所以整个表达式的类型始终是bool,完全匹配你声明的类型注解。
内容的提问来源于stack exchange,提问作者thearchitector
相关产品推荐
相关产品推荐

