@@ -8,29 +8,36 @@ kernelspec:
88 language : python
99 name : python3
1010heading-map :
11+ More Language Features : 更多语言特性
1112 Overview : 概述
12- Iterables and Iterators : 可迭代对象与迭代器
13- Iterables and Iterators::Iterators : 迭代器
14- Iterables and Iterators::Iterators in For Loops : For 循环中的迭代器
15- Iterables and Iterators::Iterables : 可迭代对象
16- Iterables and Iterators::Iterators and built-ins : 迭代器与内置函数
17- ' `*` and `**` Operators ' : ' `*` 和 `**` 运算符'
18- ' `*` and `**` Operators::Unpacking Arguments ' : 解包参数
19- ' `*` and `**` Operators::Arbitrary Arguments ' : 任意数量的参数
20- Decorators and Descriptors : 装饰器与描述符
21- Decorators and Descriptors::Decorators : 装饰器
22- Decorators and Descriptors::Decorators::An Example : 一个示例
23- Decorators and Descriptors::Decorators::Enter Decorators : 引入装饰器
24- Decorators and Descriptors::Descriptors : 描述符
25- Decorators and Descriptors::Descriptors::A Solution : 解决方案
26- Decorators and Descriptors::Descriptors::How it Works : 工作原理
27- Decorators and Descriptors::Descriptors::Decorators and Properties : 装饰器与属性
13+ Iterables and iterators : 可迭代对象与迭代器
14+ Iterables and iterators::Iterators : 迭代器
15+ Iterables and iterators::Iterators in for loops : for 循环中的迭代器
16+ Iterables and iterators::Iterables : 可迭代对象
17+ Iterables and iterators::Iterators and built-ins : 迭代器与内置函数
18+ ' `*` and `**` operators ' : ' `*` 和 `**` 运算符'
19+ ' `*` and `**` operators::Unpacking arguments ' : 解包参数
20+ ' `*` and `**` operators::Arbitrary arguments ' : 任意数量的参数
21+ Type hints : 类型提示
22+ Type hints::Basic syntax : 基本语法
23+ Type hints::Common types : 常用类型
24+ Type hints::Hints don't enforce types : 提示不强制类型
25+ Type hints::Why use type hints? : 为什么使用类型提示?
26+ Type hints::Type hints in scientific Python : 科学 Python 中的类型提示
27+ Decorators and descriptors : 装饰器与描述符
28+ Decorators and descriptors::Decorators : 装饰器
29+ Decorators and descriptors::Decorators::An example : 一个示例
30+ Decorators and descriptors::Decorators::Enter decorators : 引入装饰器
31+ Decorators and descriptors::Descriptors : 描述符
32+ Decorators and descriptors::Descriptors::A solution : 解决方案
33+ Decorators and descriptors::Descriptors::How it works : 工作原理
34+ Decorators and descriptors::Descriptors::Decorators and properties : 装饰器与属性
2835 Generators : 生成器
29- Generators::Generator Expressions : 生成器表达式
30- Generators::Generator Functions : 生成器函数
31- Generators::Generator Functions ::Example 1 : 示例 1
32- Generators::Generator Functions ::Example 2 : 示例 2
33- Generators::Advantages of Iterators : 迭代器的优势
36+ Generators::Generator expressions : 生成器表达式
37+ Generators::Generator functions : 生成器函数
38+ Generators::Generator functions ::Example 1 : 示例 1
39+ Generators::Generator functions ::Example 2 : 示例 2
40+ Generators::Advantages of iterators : 迭代器的优势
3441 Exercises : 练习
3542---
3643
@@ -47,14 +54,14 @@ heading-map:
4754
4855## 概述
4956
50- 关于这最后一讲,我们的建议是** 第一次阅读时跳过它* * ,除非你迫切想要阅读。
57+ 关于这最后一讲,我们的建议是* 第一次阅读时跳过它* ,除非你迫切想要阅读。
5158
5259它在这里有两个用途:
5360
54611 . 作为参考,以便我们在需要时可以链接回来,以及
55621 . 供那些已经完成了许多应用练习、现在想要深入了解 Python 语言的人使用。
5663
57- 本讲涵盖了多种主题,包括迭代器、装饰器和描述符,以及生成器。
64+ 本讲涵盖了多种主题,包括迭代器、类型提示、 装饰器和描述符,以及生成器。
5865
5966## 可迭代对象与迭代器
6067
@@ -66,6 +73,7 @@ heading-map:
6673现在让我们更仔细地了解它的工作原理,重点关注 Python 中 ` for ` 循环的实现。
6774
6875(iterators)=
76+
6977### 迭代器
7078
7179``` {index} single: Python; Iterators
@@ -155,7 +163,7 @@ next(nikkei_data)
155163next(nikkei_data)
156164```
157165
158- ### For 循环中的迭代器
166+ ### for 循环中的迭代器
159167
160168``` {index} single: Python; Iterators
161169```
@@ -486,6 +494,107 @@ arb(l1=l1, l2=l2, l3=l3)
486494
487495区别在于带有 ` *args ` 的函数能够接受任意大小的* 位置参数* ,而 ` **kargs ` 允许函数接受任意数量的* 关键字参数* 。
488496
497+ ## 类型提示
498+
499+ ``` {index} single: Python; Type Hints
500+ ```
501+
502+ Python 是一种* 动态类型* 语言,这意味着您无需声明变量的类型。
503+
504+ (请参阅我们{doc}` 之前关于 <need_for_speed> ` 动态类型与静态类型的讨论。)
505+
506+ 然而,Python 支持可选的** 类型提示** (也称为类型注解),允许您指定变量、函数参数和返回值的预期类型。
507+
508+ 类型提示从 Python 3.5 开始引入,并在后续版本中不断发展。此处展示的所有语法均适用于 Python 3.9 及更高版本。
509+
510+ ``` {note}
511+ 类型提示*在运行时会被 Python 解释器忽略*——它们不会影响代码的执行方式。它们纯粹是信息性的,作为供人类和工具使用的文档。
512+ ```
513+
514+ ### 基本语法
515+
516+ 类型提示使用冒号 ` : ` 来注解变量和参数,使用箭头 ` -> ` 来注解返回类型。
517+
518+ 下面是一个简单的示例:
519+
520+ ``` {code-cell} python3
521+ def greet(name: str, times: int) -> str:
522+ return (name + '! ') * times
523+
524+ greet('hello', 3)
525+ ```
526+
527+ 在这个函数定义中:
528+
529+ - ` name: str ` 表示 ` name ` 预期为字符串类型
530+ - ` times: int ` 表示 ` times ` 预期为整数类型
531+ - ` -> str ` 表示该函数返回一个字符串
532+
533+ 您也可以直接注解变量:
534+
535+ ``` {code-cell} python3
536+ x: int = 10
537+ y: float = 3.14
538+ name: str = 'Python'
539+ ```
540+
541+ ### 常用类型
542+
543+ 最常用的类型提示是内置类型:
544+
545+ | 类型 | 示例 |
546+ | -----------| ----------------------------------|
547+ | ` int ` | ` x: int = 5 ` |
548+ | ` float ` | ` x: float = 3.14 ` |
549+ | ` str ` | ` x: str = 'hello' ` |
550+ | ` bool ` | ` x: bool = True ` |
551+ | ` list ` | ` x: list = [1, 2, 3] ` |
552+ | ` dict ` | ` x: dict = {'a': 1} ` |
553+
554+ 对于容器类型,您可以指定其元素的类型:
555+
556+ ``` {code-cell} python3
557+ prices: list[float] = [9.99, 4.50, 2.89]
558+ counts: dict[str, int] = {'apples': 3, 'oranges': 5}
559+ ```
560+
561+ ### 提示不强制类型
562+
563+ 对于 Python 新手来说,有一个重要的点需要注意:类型提示在运行时* 不会被强制执行* 。
564+
565+ 如果您传入"错误"的类型,Python 不会抛出错误:
566+
567+ ``` {code-cell} python3
568+ def add(x: int, y: int) -> int:
569+ return x + y
570+
571+ # Passes floats — Python doesn't complain
572+ add(1.5, 2.7)
573+ ```
574+
575+ 提示说明参数类型为 ` int ` ,但 Python 欣然接受 ` float ` 参数并返回 ` 4.2 ` ——同样不是 ` int ` 。
576+
577+ 这与 C 或 Java 等静态类型语言有着关键区别,在那些语言中,类型不匹配会导致编译错误。
578+
579+ ### 为什么使用类型提示?
580+
581+ 如果 Python 会忽略它们,为什么还要使用呢?
582+
583+ 1 . ** 可读性** :类型提示使函数签名具有自文档化的特性。读者可以立即了解函数期望的输入类型和返回类型。
584+ 2 . ** 编辑器支持** :VS Code 等 IDE 利用类型提示提供更好的自动补全、错误检测和内联文档功能。
585+ 3 . ** 错误检查** :[ mypy] ( https://mypy.readthedocs.io/ ) 和 [ pyrefly] ( https://pyrefly.org/ ) 等工具会分析类型提示,在您运行代码* 之前* 捕获错误。
586+ 4 . ** 大语言模型生成的代码** :大语言模型经常生成带有类型提示的代码,因此理解相关语法有助于您阅读和使用其输出结果。
587+
588+ ### 科学 Python 中的类型提示
589+
590+ 类型提示与{doc}` 性能需求 <need_for_speed> ` 的讨论密切相关:
591+
592+ * [ JAX] ( https://jax.readthedocs.io/ ) 和 [ Numba] ( https://numba.pydata.org/ ) 等高性能库依赖于了解变量类型来编译快速的机器码。
593+ * 虽然这些库在运行时推断类型,而不是直接读取 Python 类型提示,但* 概念* 是相同的——显式的类型信息能够实现优化。
594+ * 随着 Python 生态系统的发展,类型提示与性能工具之间的联系预计将进一步加强。
595+
596+ 目前,类型提示在日常 Python 开发中的主要优势在于* 清晰性和工具支持* ,随着程序规模的增长,这一优势的价值也会越来越大。
597+
489598## 装饰器与描述符
490599
491600``` {index} single: Python; Decorators
@@ -655,6 +764,7 @@ def g(x):
655764在许多人看来,这使得装饰器语法成为对语言的重大改进。
656765
657766(descriptors)=
767+
658768### 描述符
659769
660770``` {index} single: Python; Descriptors
@@ -809,6 +919,7 @@ class Car:
809919如需进一步了解,可以参考[ 描述符文档] ( https://docs.python.org/3/howto/descriptor.html ) 。
810920
811921(paf_generators)=
922+
812923## 生成器
813924
814925``` {index} single: Python; Generators
@@ -1079,7 +1190,6 @@ sum(draws)
10791190* 避免了创建大型列表/元组的需要,以及
10801191* 提供了一个统一的迭代接口,可以在 ` for ` 循环中透明地使用。
10811192
1082-
10831193## 练习
10841194
10851195
@@ -1140,4 +1250,4 @@ for date in dates:
11401250```
11411251
11421252``` {solution-end}
1143- ```
1253+ ```
0 commit comments