PEP 781 – 将 TYPE_CHECKING
设为内置常量
- 作者:
- 稻田直树 <songofacandy at gmail.com>
- 讨论至:
- Discourse 帖子
- 状态:
- 草案
- 类型:
- 标准跟踪
- 主题:
- 类型标注
- 创建日期:
- 2025年3月24日
- Python 版本:
- 3.15
- 发布历史:
- 2025年1月11日, 2025年3月24日
摘要
本PEP提议添加一个新的内置变量 TYPE_CHECKING
,以改善使用类型注解编写Python代码的体验。当代码被静态类型检查器分析时,它的值为 True
;在正常运行时执行期间,它的值为 False
。与 typing.TYPE_CHECKING
(此变量将取代它)不同,它不需要import语句。
动机
类型注解由PEP 484为Python定义,并得到了广泛采用。完全注解代码的一个挑战是,为了将相关名称引入作用域,需要更多的导入,这可能在没有仔细设计的情况下导致导入循环。这已得到PEP 563以及后来的PEP 649的认可,它们引入了两种不同的机制用于类型注解的延迟评估。正如PEP 563所指出的,“类型提示……不是计算免费的”。因此引入了typing.TYPE_CHECKING
常量,最初是为了帮助打破循环导入。
在启动时间至关重要的情况下,例如命令行界面、应用程序或核心库中,程序员可能会将所有运行时不需要的导入语句放在“TYPE_CHECKING块”内,甚至将某些导入推迟到函数内部。typing
模块本身可能需要多达10毫秒的导入时间,比Python初始化所需的时间还要长。导入 typing
模块所需的时间显然不容忽视。
为了避免从 typing
中导入 TYPE_CHECKING
,开发人员目前会定义一个模块级变量,例如 TYPE_CHECKING = False
或使用类似 if False: # TYPE_CHECKING
的代码。提供一个标准方法将允许许多工具一致地实现相同的行为。它还将允许生态系统中的第三方工具标准化为具有保证语义的单一行为,例如一些静态类型检查器目前不允许局部常量,只识别 typing.TYPE_CHECKING
。
规范
TYPE_CHECKING
是一个内置常量,其值为 False
。与 True
、False
、None
和 __debug__
不同,TYPE_CHECKING
不是一个真正的常量;对其赋值不会引发 SyntaxError
。
静态类型检查器必须将 TYPE_CHECKING
视为 True
,类似于 typing.TYPE_CHECKING
。
如果本PEP被接受,新的 TYPE_CHECKING
常量将成为首选方法,而导入 typing.TYPE_CHECKING
将被弃用。为了最大限度地减少类型化对运行时的影响,此弃用将不早于 Python 3.13 的生命周期结束(计划于2029年10月)生成 DeprecationWarning
。
相反,当被检查程序的目标版本被标记为Python 3.14或更高版本时,类型检查器可能会警告此类已弃用的用法。
向后兼容性
由于 TYPE_CHECKING
不禁止赋值,因此使用 TYPE_CHECKING
的现有代码将继续工作。
# This code will continue to work
TYPE_CHECKING = False
from typing import TYPE_CHECKING
用户在停止使用 Python 3.13 或更早版本后,可以删除对 TYPE_CHECKING
的赋值。
如何教授此内容
- 使用
if TYPE_CHECKING:
在运行时跳过类型检查代码。 - 使用
from typing import TYPE_CHECKING
以支持 3.14 之前的 Python 版本。 - 诸如
TYPE_CHECKING = False
或if False: # TYPE_CHECKING
等变通方法将继续有效,但不建议使用。
参考实现
被拒绝的想法
消除仅用于类型检查的代码
考虑添加一个名为 __type_checking__
的真正常量,以在编译时消除仅用于类型检查的代码。
然而,向语言中添加真正的常量会增加语言的复杂性。消除仅用于类型检查的代码所带来的好处被认为不足以证明这种复杂性是合理的。
优化 import typing
未来的优化可能会消除为了启动时间而避免导入 typing
模块的必要性。
即使有这样的优化,仍然存在最小化导入有益的用例,例如在嵌入式系统或浏览器中运行Python。
因此,定义一个常量用于跳过 typing
模块之外的仅类型检查代码仍然很有价值。
版权
本文档置于公共领域或 CC0-1.0-Universal 许可证下,以更宽松者为准。
来源: https://github.com/python/peps/blob/main/peps/pep-0781.rst
最后修改: 2025-05-06 20:54:28 GMT