Python中内置函数all检查字典时的静态类型校验问题
问题:mypy无法识别
all()推导式中的类型窄化 我定义了如下字典:
my_dict: Dict[str, int | None] = {}
我想要检查其中是否存在key1和key2两个特定键,若存在且对应值非None,则更新key1的值:
if all(key in my_dict and my_dict[key] for key in ("key1", "key2")): my_dict["key1"] += my_dict["key2"]
但mypy提示错误:
test.py:4: error: Unsupported operand types for + ("int" and "None") [operator] test.py:4: error: Unsupported operand types for + ("None" and "int") [operator] test.py:4: error: Unsupported left operand type for + ("None") [operator]
我的临时解决方法是:
if ( all(key in my_dict for key in ("key1", "key2")) and my_dict["key1"] and my_dict["key2"] ): my_dict["key1"] += my_dict["key2"]
这种写法不够优雅,想请教为何第一种写法无法通过类型检查?
原因分析
- mypy的类型窄化逻辑无法穿透
all()函数内的生成器表达式。生成器里的key in my_dict and my_dict[key]虽然能在运行时验证键存在且值非None,但mypy无法将这个验证结果关联到后续代码中对my_dict["key1"]和my_dict["key2"]的访问——它仍然认为这两个键对应的值可能是None。 - 生成器表达式是惰性求值的,mypy不会对其中的每一项做细致的类型跟踪,尤其是当循环变量为动态值(比如这里的
key)时,它无法把特定键的类型窄化信息保留下来。
更优雅的替代写法
方法1:显式提取值并验证
key1_val = my_dict.get("key1") key2_val = my_dict.get("key2") if key1_val is not None and key2_val is not None: my_dict["key1"] = key1_val + key2_val
方法2:使用类型断言(适合简单场景)
from typing import cast if all(key in my_dict and my_dict[key] is not None for key in ("key1", "key2")): my_dict["key1"] = cast(int, my_dict["key1"]) + cast(int, my_dict["key2"])
方法3:利用海象运算符(Python 3.8+)
if (key1_val := my_dict.get("key1")) is not None and (key2_val := my_dict.get("key2")) is not None: my_dict["key1"] = key1_val + key2_val
内容的提问来源于stack exchange,提问作者Pavlo
相关产品推荐
相关产品推荐

