Python引入渐进式Type Hint机制 静态检查直击大型项目维护痛点

【python】Type Hint入门与初探,好好的python写什么类型标注? — 码农高天

码农高天

Python通过渐进式类型标注与mypy静态检查在编码阶段拦截缺陷,且完全不产生运行时性能损耗。

AI-assisted summary of 【python】Type Hint入门与初探,好好的python写什么类型标注? — original source. Check the original for full context.

Source published:

Key ideas

  • Python 自 3.5 起引入 Type Hint,旨在解决大型项目与多人协作中因动态类型造成的代码可读性差及维护成本高问题。 (0:00)
  • 类型标注可通过 mypy 等静态分析工具与现代 IDE 在运行前捕获类型缺陷,且运行时几乎零性能损耗。 (0:00)
  • 从 Python 3.9 开始内置容器直接支持泛型(如 list[int]),typing.List 进入弃用流程;Python 3.10 则引入管道符(如 int | None)简化联合类型书写。 (5:00)
  • Python 采用渐进式类型(Gradual Typing)设计,老项目无需重写即可按需逐步添加注解并享受静态检查收益。 (10:00)

Detailed notes

## Background 本视频由“码农高天”于 2024 年 2 月 11 日发布在 YouTube 平台。视频简介指出,本期内容围绕 Python 的 Type Hint(类型标注)展开,系统探讨编写类型标注的原因、核心优势以及最常见的标注实践,旨在帮助开发者更深入地理解并尝试使用这一特性。

## TL;DR 视频从 Python 动态类型在团队协作和大型项目维护中的痛点切入,阐述了类型标注在提升可读性、强化现代 IDE 提示以及配合 mypy 静态分析提前排错的三大优势。接着深入讲解了基础类型、自定义类自引用(字符串注解方案)、容器元素标注(list[int] 与向后兼容的历史演进),以及更推荐的 Sequence 抽象序列用法。随后解析了 Union、Optional 与 Python 3.10 管道符(|)等联合类型的实现形式。最后重点总结了 Python 类型标注所蕴含的“运行时无性能损耗”与“渐进式类型系统”这两大优秀软件工程哲学,证明旧项目可以无负担、平滑地逐步引入类型规范。

## Atmosphere & style 讲解风格清晰透彻、严谨务实,体现出资深工程实践者与开源维护者的从容与洞察力。高天善于通过通俗的比喻(如自引用标注中“先有鸡还是先有蛋”)化解生硬的概念,结合实际开发细节层层递进。整体节奏舒缓自如、富有逻辑美感,不仅传授具体的语法规范,更传递了优雅、温和的工程演化理念,给人一种专业、接地气且极具启发性的视听感受。

## Bulletin - [00:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=0s) Python 自 3.5 起引入 Type Hint,旨在解决大型项目与多人协作中因动态类型造成的代码可读性差及维护成本高问题。 - [00:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=0s) 类型标注可通过 mypy 等静态分析工具与现代 IDE 在运行前捕获类型缺陷,且运行时几乎零性能损耗。 - [05:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=300s) 从 Python 3.9 开始内置容器直接支持泛型(如 list[int]),typing.List 进入弃用流程;Python 3.10 则引入管道符(如 int | None)简化联合类型书写。 - [10:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=600s) Python 采用渐进式类型(Gradual Typing)设计,老项目无需重写即可按需逐步添加注解并享受静态检查收益。

## Key takeaways - [00:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=0s) 动态类型语言在项目规模扩大后容易产生类型错误,Type Hint 能显式展示参数与返回值预期,极大减轻阅读认知负担。 - [00:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=0s) 在函数签名中,使用冒号声明入参类型(如 a: int),使用箭头声明返回值类型(如 -> int)。 - [00:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=0s) 通过终端运行 mypy 或在 VS Code 的 settings.json 中开启 mypy 检查,可以在代码未执行前直接定位类型不匹配错误。 - [05:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=300s) 所有内置基础数据类型(int、str、float 等)及自定义类均可直接作为类型注解,自定义类要求传入其实例对象而非类对象本身。 - [05:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=300s) 在类定义体内自引用自身类型时(如链表节点的前驱引用),使用字符串字面量(如 prev: "Node")可解决尚未定义的“先有鸡还是先有蛋”问题。 - [05:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=300s) 仅标注 list 无法约束容器内部类型,Python 3.9+ 推荐使用内置小写 list[int],若需兼容 3.9 之前版本则需从 typing 导入 List。 - [05:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=300s) 为了让函数接口更通用,接受序列传参时推荐使用 typing.Sequence[int],可同时兼容 list、tuple、range 等对象。 - [05:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=300s) 字典类型需要同时指定键与值的类型,在方括号内用逗号分隔(如 dict[str, int])。 - [10:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=600s) 支持多类型或允许 None 的参数可以使用 typing.Union 或 typing.Optional,二者在表达可选类型时等价。 - [10:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=600s) Python 3.10 引入了管道符语法(如 int | None),取代了繁琐的 typing 导入并提升了代码简洁度。 - [10:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=600s) Type Hint 遵循运行时无惩罚(No Runtime Penalty)原则,增加类型标注几乎不会对程序执行速度造成负面影响。 - [10:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=600s) 渐进式类型系统允许开发者在新代码或核心模块中逐步采用类型标注,无需对遗留代码进行一次性全部重构。

## Detailed walkthrough ### [00:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=0s) 为什么要在 Python 中写类型标注(Type Hint)?

Python 作为一种动态类型语言,变量的类型是在运行时(runtime)决定的。这种灵活性虽然让早期的编码速度变得非常快,但随着项目代码量不断膨胀,类型不匹配引发的错误会逐渐增加,给团队协作和大型项目维护带来了明显的效率损耗。码农高天指出:“尤其在你跟其他人合作的时候,有时候你写的程序他可能一眼看不明白这个变量到底是什么东西。”为了解决这一痛点,Python 自 3.5 版本起逐步引入了 Type Hint(类型标注/类型提示),允许开发者以可选的方式显式标注变量和函数签名的类型。

以一个最基本的求和函数 `def f(a, b): return a + b` 为例,原始代码无法让人一眼看出入参和返回值究竟是什么。通过引入标注语法,将其改写为: ```python def f(a: int, b: int) -> int: return a + b ``` 参数名后跟冒号与类型(如 `a: int`)代表输入变量的期望类型,函数参数列表括号与冒号之间的箭头加类型(`-> int`)则代表返回值类型。这样做带来了三大核心好处:

1. **增强代码可读性**:在维护遗留代码或阅读他人代码时,光靠阅读实现往往很难确认一个变量究竟是 `list`、`int`、特定对象实例还是有可能为 `None`。类型标注直接将这些上下文呈现出来,省去了反复翻查函数实现的认知负担。 2. **现代编辑器支持**:现代 IDE 与编辑器(如 VS Code)能直接读取类型标注,在开发者调用外部函数或第三方库时自动提示参数与返回类型,无需深入阅读源码。 3. **提前暴露逻辑错误**:如果传入了一个 `str` 和一个 `int`,在纯动态环境下只能等到运行时才能抛错。而配合静态分析工具(Static Analysis Tool),开发者在运行代码前就能定位类型缺陷。

在 Python 生态中,最主流的静态类型检查工具是 `mypy`。在环境中通过 `pip install mypy` 安装后,只需执行 `mypy example.py` 即可对文件进行静态检查。如果函数期望 `int` 却传入了字符串,`mypy` 会直接在终端指出具体行数与参数类型不符的问题。若使用 VS Code,可以通过按 `Ctrl+Shift+P` 打开设置文件 `settings.json`,配置 `"python.linting.mypyEnabled": true`,从而将类型错误直接以波浪线的形式标红在编辑器窗口内,实现编码阶段的实时纠错。

```mermaid flowchart LR accTitle: Static Analysis Flow accDescr: A diagram showing how static analysis tools check Python source code without running it. subgraph Code["编写阶段"] A["Python 源代码<br/>(带 Type Hint)"] end subgraph Tool["静态分析"] B["mypy 检查器"] C["VS Code 实时反馈"] end subgraph Result["执行结果"] D["提前发现类型错误<br/>(无需运行)"] end A --> B A --> C B --> D C --> D ```

---

[05:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=300s) 常用类型标注:内置类型、自定义类与容器(Container)

在日常编码中,Python 所有内置的基础数据类型(如 `int`、`float`、`str`)都可以直接作为类型标注使用。对于自定义类型,类名本身也可以作为类型注解。例如定义了 `class A`,当编写 `def get_name(item: A) -> str` 时,入参必须是类 `A` 的实例对象(Instance),若直接传入类对象本身 `A`(其类型为 `type A`)或是其他基本类型,`mypy` 都会抛出类型错误。

自定义类标注中存在一个特殊的经典问题:当在类的方法中需要将参数类型标注为该类本身时(例如实现双向链表时,`Node` 类的 `__init__` 初始化方法需要传入前驱节点 `prev: Node`),静态检查器通常会报错提示 `Node` 尚未定义。码农高天将这一现象形容为“先有鸡还是先有蛋的问题”:在类的定义体内部,当前类对象还没有创建完毕,无法在局部作用域中解析该名称。针对这种循环依赖或未就绪的引用,规范的解决方案是将类型名称用引号包裹起来变成字符串字面量(例如 `prev: "Node"`)。这种延后求值(deferred evaluation)的字符串形式完全合法,并受到 `mypy` 的正式支持。

对于容器类型的标注,直接标注 `lst: list` 仅能限定它是一个列表,但无法约束列表内部元素的类型;此时即便在列表中混入非预期类型,`mypy` 也无法捕获。因此,更准确的做法是约束其内部元素的类型: - **容器元素标注**:在 Python 3.9 及以后的版本中,可以直接在内置容器后加方括号指明内部类型,如 `list[int]` 表示包含纯整数的列表。 - **历史版本兼容性与弃用策略**:在 Python 3.9 之前,标准 `list` 并不支持中括号类型参数索引,开发者必须从内置库 `typing` 中引入大写的 `List`(即 `from typing import List`)。然而从 Python 3.9 开始,`typing.List` 已被标记为 Deprecated(已废弃),按照官方规划将在该特性发布后的 5 年逐步从标准库中移除。因此,如果项目需要向前兼容 3.9 以前的 Python 版本(如高天维护的 VizTracer 项目),需要继续使用 `typing.List`;若项目仅支持 3.9+,则应当直接采用内置小写的 `list[int]`。

在实际函数接口设计中,直接要求参数为 `list` 往往过于严苛,因为调用方常常会传入元组(`tuple`)等其他有序序列。若标注为 `list[int]` 却传入 `(1, 2, 3)`,`mypy` 会直接判定类型不匹配。更地道、更通用的做法是采用更抽象的序列类型: ```python from typing import Sequence

def sum_all(lst: Sequence[int]) -> int: return sum(lst) ``` 使用 `Sequence[int]` 作为参数注解,不仅兼容 `list` 和 `tuple`,还可以无缝接受 `range` 对象甚至 `bytes`。

字典类型则需要同时标注键(Key)和值(Value)的类型,并在方括号内以逗号隔开,例如 `dict[str, int]` 表示键为字符串、值为整数的字典映射。

---

[10:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=600s) 多重类型、None 值处理与 Type Hint 的工程哲学

在实际业务逻辑中,一个参数常常允许接受多种可能的类型,最典型的一种模式是传入某个实体类型或传入 `None` 来表示默认/缺省参数(例如 `if x is None:... else:...`)。为了覆盖多类型传参场景,Python 提供了联合类型工具: - **`Union`**:通过 `from typing import Union` 引入,例如 `x: Union[int, None]` 表示参数既可以是整数也可以是 `None`。`Union` 的方括号内可以传入两个或两个以上的任意类型。 - **管道符 `|`**:从 Python 3.10 开始,Python 引入了类似 C 语言位或运算符的语法糖,支持直接写成 `int | None`,大大简化了书写(在 3.9 或更早版本中使用该语法会触发语法错误)。 - **`Optional`**:由于“可能是某类型或可能为 `None`”的模式极其常见,标准库还提供了更具语义表达力的 `Optional`(即 `Optional[int]`,等价于 `Union[int, None]`)。

在视频结尾,码农高天分享了 Python 在推广类型标注时所展现出的两项优秀软件工程理念:

1. **运行时无惩罚(No Runtime Penalty)**:类型标注在 Python 运行时几乎不产生任何性能损耗,程序不会因为增加了详尽的类型注解而变慢。码农高天强调:“这是一个非常好的工程理念,就是我引入一些新的 feature 不会让我这个东西变得更差。” 2. **渐进式类型系统(Gradual Typing)**:开发者不需要在非黑即白之间做选择,现有的老项目完全不需要为了引入 Type Hint 而一次性重写所有代码。你可以在函数中逐步、渐进地加入标注——加了类型标注的部分,静态检查工具会协助分析排错;没有加的地方,Python 依旧当作常规动态类型代码正常解释执行。这种渐进特性让工程团队可以在“无伤”的前提下逐步尝试,感受静态类型检查带来的收益,并平滑地将旧工程迁移到更规范的代码体系中。

- **`Union[int, None]` 与 `Optional[int]`**:二者完全等价,均指代值可以是 `int` 或 `None`。 - **Python 3.10 语法糖**:`int | None` 直接替代繁琐的 `Union` 导入与写法。 - **双向链表类型标注示例**:在节点类声明自身引用时,写为 `prev: "Node"` 解决名称未定义与自引用解析问题。

## Notable quotes > [10:00](https://www.youtube.com/watch?v=HYE85bqNoGw&t=600s) 这是一个非常好的工程理念,就是我引入一些新的 feature 不会让我这个东西变得更差。 — 码农高天

## Mentioned Python, mypy, VS Code, VizTracer, 码农高天

## Video description 这期视频聊一下type hint,也就是类型标注。我们聊一下为什么要做这件事,有什么好处,然后再说一下最常见的类型标注要怎么做。希望大家对这个python家庭新的功能有一个更深入的认识,并且开始尝试使用它。

[Source](https://www.youtube.com/watch?v=HYE85bqNoGw)

中文简报

Python引入渐进式Type Hint机制 静态检查直击大型项目维护痛点 Python通过渐进式类型标注与mypy静态检查在编码阶段拦截缺陷,且完全不产生运行时性能损耗。 视频从 Python 动态类型在团队协作和大型项目维护中的痛点切入,阐述了类型标注在提升可读性、强化现代 IDE 提示以及配合 mypy 静态分析提前排错的三大优势。接着深入讲解了基础类型、自定义类自引用(字符串注解方案)、容器元素标注(list[int] 与向后兼容的历史演进),以及更推荐的 Sequence 抽象序列用法。随后解析了 Union、Optional 与 Python 3.10 管道符(|)等联合类型的实现形式。最后重点总结了 Python 类型标注所蕴含的“运行时无性能损耗”与“渐进式类型系统”这两大优秀软件工程哲学,证明旧项目可以无负担、平滑地逐步引入类型规范。 Python 自 3.5 起引入 Type Hint,旨在解决大型项目与多人协作中因动态类型造成的代码可读性差及维护成本高问题。 (0:00) 类型标注可通过 mypy 等静态分析工具与现代 IDE 在运行前捕获类型缺陷,且运行时几乎零性能损耗。 (0:00) 从 Python 3.9 开始内置容器直接支持泛型(如 list[int]),typing.List 进入弃用流程;Python 3.10 则引入管道符(如 int | None)简化联合类型书写。 (5:00) Python 采用渐进式类型(Gradual Typing)设计,老项目无需重写即可按需逐步添加注解并享受静态检查收益。 (10:00)

Reading summary

码农高天指出,Python 引入类型标注(Type Hint)旨在解决动态类型在大型项目与多人协作中的可读性和维护痛点,配合静态分析工具可以在运行前排查逻辑错误。该机制依托渐进式类型设计,在提升工程健壮性的同时不会对 Python 产生运行时性能损耗。 解决动态类型痛点与静态检查工具 (0:00) Python 的变量类型在运行时决定,这种灵活性在项目规模扩大与团队协作时容易引发类型不匹配问题,导致阅读与维护成本上升。自 Python 3.5 起引入的 Type Hint 允许开发者显式标注函数入参和返回值(例如 `def f(a: int, b: int) -> int:`),这显著提升了代码上下文的可读性,并为现代 IDE(如 VS Code)提供了准确的代码补全与参数提示能力。 静态检查与开发环境集成 (0:00) 类型标注本身不强制运行时类型约束,其主要价值在于配合静态分析工具在运行前拦截缺陷。以主流检查工具 `mypy` 为例,开发者可在终端执行检查,或在 VS Code 的 `settings.json` 中配置 `"python.linting.mypyEnabled": true`,将类型不匹配的问题以实时波浪线形式标红,从而在编码阶段暴露潜在的传参错误。 自定义类自引用与容器版本演进 (5:00) 内置基础类型和自定义类均可作为标注,但若在类内部的方法中声明该类自身类型(如双向链表的 `prev: Node`),会遇到类尚未构建完成的“先有鸡还是先有蛋”问题;标准解决方案是将类名写为字符串字面量(如 `prev: "Node"`)进行延迟求值。对于容器类型,标注内部元素能提供更精确的约束:Python 3.9 及以上版本支持直接使用内置小写类型(如 `list[int]`),而 3.9 之前则需从 `typing` 模块导入大写的 `List`。考虑到 `typing.List` 在 3.9 中已被标记为废弃并计划移除,仅需向后兼容旧版(如 VizTracer 项目)时才需保留旧写法。 抽象序列接口与联合类型表达 (10:00) 在接口设计中,直接标注 `list[int]` 会拒绝元组等合法有序输入;更规范的工程做法是采用 `from typing import Sequence` 标注为 `Sequence[int]`,以兼容 `list`、`tuple`、`range` 乃至 `bytes`。当参数支持多种类型或缺省为 `None` 时,可以使用 `Union[int, None]` 或完全等价的语义化写法 `Optional[int]`。自 Python 3.10 起,还引入了管道符语法糖(如 `int | None`),进一步简化了多类型的书写。 类型标注背后的工程设计理念 (10:00) Python 类型系统的推广体现了两项核心工程原则:一是运行时无惩罚(No Runtime Penalty),类型注解在程序运行阶段几乎不产生额外开销,不会使程序变慢;二是渐进式类型系统(Gradual Typing),遗留工程无需推倒重来,团队可以在现有代码中逐个函数渐进添加标注。未标注部分保持原有动态执行逻辑,已标注部分则享受静态检查红利,实现了工程平滑迁移。 类型标注结合静态工具显著提升了 Python 在复杂项目中的可维护性,但开发者在采用时需留意版本兼容性差异,例如 Python 3.10 引入的管道符语法以及 Python 3.9 对 `typing.List` 的废弃规划。

Source quotes

[10:00] 码农高天: 这是一个非常好的工程理念,就是我引入一些新的 feature 不会让我这个东西变得更差。

Original transcript

[0:00] 这期视频我们来讲一个相对实用性比较强的内容 叫做Type Hint中文有的叫类型标注啊有的叫类型提示那我们都知道呢 Python 是一个动态类型语言就是它每一个变量是什么类型呢 是在它run time的时候决定的这种特性当然有好处它很灵活 然后让我们写代码的速度变得非常快但是当我们的代码量上去之后有的时候我们就会觉得由类型不对引发的错误会逐渐增加然后由这种动态类型引发的编程效率降低会越来越明显尤其在你跟其他人合作的时候有时候你写的程序他可能一眼看不明白这个变量到底是什么东西那么从 Python 3.5 版本开始就逐渐的引入了这个叫 type hint或者叫Type annotation就是让你在写python的时候可以可选的标注变量类型我们先快速的举一个例子然后我们来说一说这样有什么好处我们看左边这个代码非常简单就是fab然后return一个a+b那么光看这个f 我们是不知道输入变量的类型是什么 也不知道返回值是什么的那我们可以在函数上进行如下的标注大家可以看,我在输入参数A和B的后面,都加了一个冒号int然后在F的冒号之前加了一个箭头int大家不难想象输入变量冒号后面的这个东西就是输入值的类型而箭头后面的这个就是返回值的类型好 进行标注之后有什么好处呢第一 函数的可读性会增强我们现在这个return a+b非常简单但是大家想象一下如果这个函数相对复杂的话当你不是这个函数的作者 或者你是很久之前写的这个函数的情况下你很有可能会不记得或者不知道每一个参数它的类型是什么这就会给你的理解带来很大的困难这个变量它是不是一个list是不是一个integer或者它是某一种特定的object它有没有可能是难你就会发现你缺少了很多理解需要的信息你就要再进去读代码有时候代码还不会告诉你这些事第二个好处 当你使用这个函数的时候你会发现所有的比较现代化的ID也好editor也好它都会显示这个函数的输入参数跟输出值是什么type了我们在使用其他人的裤子的时候是很少进去读它的原代码的 除非你像我一样喜欢去读原代码那我们调用的时候知道每个变量是什么类型实际上是对我们的调用有非常大的帮助的第三,它确实能帮我们解决一些由类型导致的逻辑问题比如我们看如果我们的f两个变量输入的分别是一个string跟一个integer他们两个是没法加的那如果没有类型标注的话这种情况我们一般只有到run time 也就是到运行的时候才能给你报错但是现在由于有了这个type hint我们不用运行它就能发现错误这种不运行程序就分析代码的工具,我们叫做static analysis tool静态分析工具那python最常用的有关类型的静态分析工具就是mypy大家如果想安装的话就是pip install mypy当然我这个虚拟环境下已经安装好了MyPi的基础使用也非常简单如果我们要分析example.py这个文件,只需要mypy example.py可以看到这里他就报错了他说在第四行F的第一个argument应该是int 但是你给了string那如果我们把第四行代码改成F1,2再运行买派他就会成功了那当然在VSCode里面你实际上是可以直接启用mypy的检查的我们可以Ctrl+Shift+P然后打开工作区设置或者直接打开全局的设置在这个settings.json里面加上这么一行叫python.linting.mypyenabled是true我们再返回刚才的程序可以看到这一块他就报错了他会在editor里面直接给你显示这个错误这样你就更容易在编程的过程中发现自己的逻辑问题好 接下来我们说一些有关使用的问题我们这一期视频是关于类型提示的一个入门所以我们只介绍一些最常用最简单的情况未来 [5:00] 如果大家对这个感兴趣呢 我们可以接着深入的去聊一些跟type in有关的问题首先就像大家看到的Python的这些built-in的类型都可以直接拿来做类型提示比如说 intFloat,String我相信大家都有举一反三的能力这里我们就不一一介绍了那另外一种非常常见的情况呢就是我们自定义的数据类型比如说我们现在定义了一个class A然后我们定义了一个函数get name让它的输入参数的类型是A当然返回值是一个street这个时候我们就可以看到第7行他就报错了因为当我们输入A的时候这个A的类型是type A 就是A的type而在第8行我们输入的才是一个A的instance一个A的对象这才是正确的当然这里输入string float integer都会报错这种自定义的类型 我们要说一个特殊情况有的时候我们在class的method里面输入的参数类型可能就是这个class本身一个最简单的例子就是我们现在举的双向链表假设在initialization的时候 我们要给出上一个node是什么这个时候你会发现买派报错了这里报错的原因是这个函数在class里面被定义的时候这个class还没有出现回忆一下我们之前视频讲的内容这个node还没有被定义那像这种先有机还是先有弹的问题怎么办呢我们可以把这个node两边加上引号让它变成一个string这样就解决了这个循环依赖的问题那实际上所有你想以后再做evaluation的拍片的都可以放到这个双眼号里面它就作为一个string literal这是一个合法的操作然后也是被买派政可的那还有非常常见的情况就是python built-in的一些container 最常见的比如说list跟dictionary比如这里我们写了一个非常简单的求和函数把list里面所有的值都做一个求和我们第一个想法肯定就是直接用list这个built-in的type那也可以看到在第8行我们尝试传进去一个integer的时候他确实报错了但是这样就足够好了吗我们看第8行实际上是一个我们蛮常见的问题就是这个list里面的东西type可能不一样或者说它的type并不是我想要的type那这个时候 MyPi就没有报错他认为这个是合法的因为你只要求了LST的参数是个list它确实是个list所以在更多的时候我们一般情况下需要标注这个list里面是什么东西我们标注的方法是list后面加一个方括号里面写int这代表这个类似里面都应该是integer我们现在再看第8行这里就报错了他说你这里有个string不是一个integer但是大家注意一下这种list后面直接加方括号的写法是python3.9以后才支持的如果你用的是比较早期的版本的话你需要这么写你需要从typing这个库里 引迫的大写L的list然后用它来作为TypePint的类型好那Python整个Type-end System从3.5 3.6它萌芽开始直到今天它是有一些变化跟发展的那这个typing里的list实际上从python3.9版本开始就deprecated了所以如果你现在是想写一个对所有Python正在支持的版本都好用的Type-Pint你就要用Typing这个list因为它在3.9版本之前也好用那如果你的程序只需要支持python3.9核以后的版本你就要用python直接built-in的list因为typing的list在python3.9版本发布那年的5年之后就要被移除了所以Vistracer现在是用的typing的这个list然后到3.8 3.9版本逐渐被历史淘汰之后我们就要回到正经的list好 那让我们回到函数本身你可能会觉得输入是一个list挺好但是在实际操作的时候我们经常会传跟list非常相似的tuple我们看这是我们实际编程中非常常见的操作我们经常会把list跟tuple混着传但是我们看买派在这就报错了说好的给一个list 你为什么给tupel了呢所以说在输入参数的时候我们一般情况下不用list而用它的一个更抽象的版本叫做Sequence我们看 [10:00] 更常见的做法是从typing里面import sequence然后输入值是一个sequence int那它不光对tuple可以用它对range也可以用甚至对byte也可以用这个是相对更普遍的用法那对于dictionary我们知道它是有key和value的那这里呢,我们就需要给key的类型和value的类型中间入逗号可开比如说这里我们就说D是一个key string,value是integer的dictionary我们看第8行我们给了一个并不满足这个条件的dictionary他就会报错了那我们最后再介绍一个非常常见的情况就是当我们传参的时候 我们经常会用num来表示一个特殊参数F的这个pattern是非常常见的就是如果我传进来这个东西跟num的话怎么样如果不是num的话怎么样很显然如果只用我们刚才说的那些方法是不足以覆盖这种情况的当我们传进来的参数有两个或者两个以上可能的类型的时候我们可以用Union大家看 我们x的类型是unin 方括号 int 多号 none这代表这个x 既有可能是int也有可能是 none当然这个union里面你可以再加其他的东西它可能是各种类型在python3.10版本之后这个union可以被简写成为int 然后这是or 就是这个竖线 在c里面代表or当然在python里也代表or当然因为我现在的环境是3.9所以他会报错他会告诉你这个sintax需要3.10或者更新的版本那由于一个参数有可能是一个type或者none这个pattern实在过于常见了所以python还给了他另外一种表示形式你可以用Optional int代表这个参数很可能是int但也有可能是那Optional就代表这个值有可能是难这会比Union Int9更清晰一些当然他们俩是完全等待的那我们今天讲的写法 只覆盖了一些最最基础的情况在未来有机会呢 我们会讲一些更加进阶的用法但是在结束之前呢 我想聊一下python在推广这个type hint的过程中他在工程中几个我很喜欢的实践第一type in的这件事情是几乎没有run time 惩罚的也就是说 你并不会因为写了type-pint 导致你的程序运行了更慢这是一个非常好的工程理念就是我引入一些新的feature不会让我这个东西变得更差那第二个呢叫做Gradual Typing渐进式的类型标注这里体现在你可以尝试type in的但是你并不需要把你原来的代码全部变成有type hinting的形式你不是在有和没有之间做选择而是可以渐进式的在你自己的代码里逐渐加入TypingT你加的地方我帮你检查你不加的地方我依然接受这也是一个非常好的工程理念 这可以让更多的人在无伤的情况下去尝试增加这样的feature感受到它的好处 并且逐渐把自己原来的项目迁移到这个新的feature上所以大家在做项目的时候呢也不妨尝试一下在自己的项目里增加一些type hint看是不是对自己的开发有所帮助好那这期视频就到这里希望大家有所帮助如果喜欢的话记得点一下关注别忘了意见三连哦优优独播剧场——YoYo Television Series Exclusive