Python 3.9 之你应该知道的新功能

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

距离 Python 3.9 版本发布还有一段时间(2020.05.10),但是最新的 alpha 版本(3.9.0a5)已经发布了,而且 beta 版本也快了。现在也是时候来看看有什么我们所期待的新功能,以及改进点和修复项了。这篇文章不会罗列出所有的改动项,而是列了一些对于我们开发着来说有趣的且值得关注的东西。所以,一起来看看吧。

安装 Beta 版本

为了解在 Python 3.9 的 alpba 或 beta 版本中都有些什么功能,我们首先要安装它。首先需要和你已经安装的 Python 3.8(或者其他版本)区分开,以免污染了本地解释器环境。然后安装最新版本:

image.png运行之后你可以在 IDLE 看到这样的标语信息:

image.png

新的 Dict 运算符

最值得关注的新功能点可能就是新增加的字典合并运算符 | 以及 |= 了。目前为止,你在合并字典的时候可能会选择使用下面三种方法中的一个:

image.png

上面的第一种方式使用 dict(iterable, **kwargs) 初始化了一个新的字典,第一个参数是一个普通的字典,第二个参数是一个键值对列表。这里是用 ** 运算符解析的另一个字典。

第二种方式是使用 update 方法利用第二个字典的键值对更新第一个字典。为了实现这种修改内存的方式,我们首先需要将第一个复制一份,以免修改了原来的第一个字典。

第三种,也是最后一种,在我看来是最简洁的一种。它将两个字典( d1d2 )解包后放入结果 d 中。

尽管上面的方式都是对的,我们现在有了一个新的(或者说更好的)解决方式则是使用 | 运算符:

image.png

上面第一个例子与之前展示的解包操作( d = {**d1, **d2} )极为相似。第二个例子是另一个底层内存合并的实现, d1 会使用 d2 内的数据更新自身。

拓扑排序

第二个有趣的(也有些冷门的)新功能在 functools 模块中。你可以在 TopologicalSorter 中找到它。通过这个类我们可以实现对图的拓扑排序。你可能会问,这是什么?拓扑排序是将两个用有向边 uv (从 u 指向 v )连接起来的两个节点 uv 进行排序,uv 前。

在介绍新功能之前,你可能会使用诸如 KHan 算法或者深度优先搜索来实现,不过这些算法都比较复杂。因此,现在,如果需要对依赖关系进行排序以便调度,则只需执行以下操作:

image.png

上面的例子中,我们先是使用字典创建了一个图,字典的 key 表示节点,values 表示与该节点相邻的节点的集合。然后,我们使用图创建一个 sorter 示例,并调用 static_order 方法来进行排序。注意,这个顺序可能取决于插入的顺序,因为当 2 个节点在图中的同一级别时,它们会按照插入时的顺序返回。

除了静态排序之外,这个类还支持在节点就绪的情况下并行进行处理。这对于处理诸如任务队列等非常有帮助。你可以在 Python 的库文档中找到示例。

IPv6 地址范围

Python 3.9 中引入的另一个变化是可以指定 IPv6 的地址范围。如果你对 IPv6 的地址范围还不熟悉,它可以指定一个 IP 在网络的哪个部分生效。地址范围可以通过在 IP 地址末尾指定 % 表示。例如:3FFE:0:0:1:200:F8FF:FE75:50DF%2,这里,IP 地址在范围 2 中,表示它是一个本地地址。

所以,如果你需要在 Python 中处理 IPv6 地址的话,可以像下面这样:

image.png

在使用 IPv6 地址范围的时候,有一件事需要特别注意。两个处于不同范围的地址不可以使用 Python 的基本操作符进行比较。

新的 math 方法

与此同时,在 math 模块中也增加或改进了许多功能。先从一个已有方法的改进开始吧:

image.png

以前,用于计算最大公约数的 gcd 函数只能用于两个数字参数,是的程序员不得不使用其他方式来实现多个数字输入:math.gcd(80, math.gcd(64, 152))。从 Python 3.9 开始,这个方法支持输入任意数量的数字参数了。

math 模块中首先增加的是 math.lcm 方法:

image.png

math.lcm 计算其多个参数的最小公倍数。与 GCD 一样,它也支持多个参数。

剩下的两个新功能非常相似,他们是 math.nextafermath.ulp

image.png

math.nextafter(x, y) 方法十分简单直接,它展示 x 之后的沿 y 方向的下一个浮点数,同时考虑浮点数的精度。

math.ulp 则是看起来有点奇怪,ULP 表示 “最后位置的单元”,它用于衡量数据计算的准确性。下面来使用一个简单的例子解释一下:

我们来想象一下,假设我们没有 64 位的计算机。相反,我们只有 3 个数字位。用这 3 个数字位我们可以表示 3.14,但是不能表示 3.141。对于 3.14,它最近的一个较大的数字可以表示为 3.15 。这两个数字相差一个 ULP(最后位置的单元),即 0.01。而 math.ulp 返回的结果与这个示例相似,但是表示的是与计算机的精度相匹配。想要看更恰当且写得很好的例子,请看这个链接 https://matthew-brett.github.io/teaching/floating_error.html

新的字符串方法

math 不是唯一的增加了新方法的模块。这里还有两个字符串操作中增加的很方便的方法:

image.png

这两个方法实现的功能,就和你平时使用 string[len(prefix):] 移除字符串前缀以及使用 string[:-len(suffix)] 移除字符串后缀的功能一样。这个功能很简单,是方法实现也很简单。不过如果你会频繁地使用这种操作的话,有个内置的方法也是很不错的。

彩蛋:Http Codes

最后,那就是在 http.HTTPStatus 中新增加的 HTTP 状态码啦:

image.png

来看看这些状态码,我不是很理解为什么要用它们。可以说,很高兴我终于为 “我是茶壶” 找到了处理的状态吗。当服务器返回这个状态码的时候,我可以使用 http.HTTPStatus.IM_A_TEAPOT 来提高我的生活质量了(真是讽刺,还是不要这么做了)。

总结

可能并不是所有的更改有与你的日常编程相关,但是我觉得至少前两项( |TopologicalSorter )在处理某些问题还是派得上用场的。可以说,目前 Python 3.9 还处于 Alpha 阶段,因此在 18.5.2020(第一个 beta 版本)之前,可能还有有一些其他的更改。但即便如此,你目前还是不应该使用这个版本,因为还还不稳定,不足以投入生产(至少要等到十月份吧)。

英文原文:https://martinheinz.dev/blog/21
译者:敦伟