Python函数内的变量类型标注为何未触发Dict参数数量校验异常?
问题解答
这是Python的预期行为,不属于bug。
核心原因说明
typing.Dict作为泛型容器类型,本身仅支持接收2个类型参数(分别对应字典的键类型、值类型),传入3个参数本身属于不符合规范的写法,触发TypeError是符合设计逻辑的,两种不同表现的差异来自Python对不同作用域下类型注解的求值时机不同:
- 模块全局作用域的变量注解会在模块加载时立刻求值:
你执行顶层代码时:
Python会立刻计算注解里from typing import Dict bar: Dict[int, int, int] = dict()Dict[int, int, int]的值,泛型参数数量校验失败,直接抛出TypeError: Too many parameters for typing.Dict; actual 3, expected 2。 - 函数内部的局部变量注解默认不会在运行时求值:
你写的函数内部的注解:
Python在定义函数、调用函数的过程中都不会主动去计算局部变量注解的实际值,仅会将注解作为未求值的表达式存储,自然不会触发运行时异常。from typing import Dict def foo(): bar: Dict[int, int, int] = dict() foo()
补充说明
- 如果你在模块开头添加
from __future__ import annotations开启延迟注解求值,就算是全局作用域的注解也不会在运行时立刻求值,第一段代码也不会抛出TypeError。 - Python运行时本身不会执行类型注解的校验,这类类型错误本就应该通过静态类型检查工具(如mypy、pyright)提前发现,不管是全局还是函数内部的错误写法,在静态类型检查阶段都会被标记为非法。
内容的提问来源于stack exchange,提问作者Jeyekomon
相关产品推荐
相关产品推荐

