Python 类型标注实战:从基础到 typing 模块的高级用法
本文详解如何在Python中使用typing模块进行类型标注。尽管Python动态特性允许自由赋值,但通过typing.List等泛型定义,可显著提升IDE智能提示与代码可读性。文章对比TypeScript,展示Python在类型检查上的宽松机制及Pylance的推导能力,帮助开发者平衡简洁性与工程规范。
Python 添加类型标注
Python 以简洁著称,开发者在声明变量时通常无需显式指定类型。
然而,简洁与复杂项目的需求之间存在平衡点。在构建大型项目时,开发者往往期望获得类似「静态类型语言」的强大类型检查功能以及智能的代码提示。
好消息是,Python 无需引入像 TypeScript 那样额外的编译器即可进行类型检查,其内置的 typing 工具能在一定程度上模拟「静态类型语言」的行为;但坏消息是,Python 本质上仍是动态语言,经过测试,其代码执行依然保持「自由松散」的特性。
给 Python 标注类型
首先明确本文的实验环境。
❯ python --version
Python 3.7.0
本文内容参考了 Python3.7 的中文文档。
我们可以通过以下方式声明变量及其类型:
a: int = 1
b: float = .2
print(f'{a}, {b}') # 1, 0.2
遗憾的是,在 Python 中,a: int = 1 这种写法实际上并无强制约束力,通俗来说就是「多此一举」;即便换种说法,这种用法在 Python 中也是完全可选的。
首先,a = 1 中解释器会自动将 a 推断为 int 类型,诸如 Pylance 的 Language Server 也会在我们编码时提供 int 的方法补全。

此外,即使我们将 a 的类型标注为 int,随后将 str 赋值给 a,解释器和 Language Server 也完全不会报错。如下所示。
a: int
a = '1'
print(a) # 非常迷
对于现代编译技术而言,执行上述类型检查本应毫无难度,但 Python 在此处既不报错也不警告。这可能与 Python 的设计哲学有关。
我们看看 TypeScript 是如何表现的:

TypeScript 将自己视为静态类型语言,要求开发者在编写时就确保类型的正确性。
使用 typing
尽管 Python 不强制要求类型正确性,且会自动执行强类型转换,但我们仍可享受类型标注带来的诸多便利。
例如,现在我们要定义一个函数 foo,该函数返回一个列表 dogList,列表中的元素均为我们自定义类 Dog 的实例。
如果没有类型标注,我们将无法获得智能提示,如下所示。

Python 中从不要求 List 对象内的元素具有相同类型,因此,解释器或 Language Server 也不会「吃力不讨好」地去运行程序以推断 List 中元素的类型。
自然,当你从 List 中获取元素时(例如上述的 dogList[0]),它无法告知你 List 中具体元素的类型,因此也无法提供提示(No suggestion.)。
这与实际业务场景不符,因为我们在编写代码时,列表中通常装入的是同一类型的对象。为了在获取元素时获得补全提示,我们可以使用 typing.List 结合 极简的泛型。如下所示。

我们规定,foo 返回的元素必是一个 List,且其中元素类型为 Dog 类型。此时,我们的 dogList[0] 也被识别为 Dog 类型,从而获得了补全功能。体验非常舒适。
题外话:聪明的 Pylance
实际上,Pylance 自身也能进行一定的类型推导。例如,当我们使用生成器创建列表时,Pylance 会判断该列表中元素的类型:

结语
关于 typing 的用法,还有许多内容值得探讨,我的主要参考资料为 Python3.7 的 typing 中文文档。此外,使用 Python 泛型实现函数重载相比静态类型语言显得较为繁琐(参考了 Python 实用宝典在知乎上的文章),若日后遇到合适场景,我将整理成文分享。
到此这篇关于浅谈怎么给Python添加类型标注的文章就介绍到这了,更多相关Python添加类型标注内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













