在过去四年里,Python 三次获得 TIOBE “年度语言” 奖项,四年中的三次 都由它摘得。到 2022 年年中,这门广受欢迎的编程语言依然位居 TIOBE 指数榜首。
Python 位居 2022 年 6 月 TIOBE 指数榜首。
Python 的评分为 12.74%,意味着关键词“Python”出现在大约 13% 的所有编程相关搜索引擎查询中。换句话说,互联网上每 7 到 8 个编程问题中就有一个与 Python 有关。
如今,Python 经常与数据科学和人工智能领域的重大突破相伴。实践者看重它的简洁、覆盖多种任务的大量内置与第三方库,以及强大的社区。
随着 3.11 的最终稳定版将在 2022 年 10 月 3 日发布,Python 社区可以期待多项令人欢迎的更新,包括显著的速度提升、更好的错误处理与调试能力,以及对标准库的诸多易用性改进。
Python 3.11 有哪些新功能?
Python 3.11 更新日志 几乎是无尽的修复、改进与新增条目清单,其中大多数您可能甚至不会注意到。不过,有几项关键的新功能可能会在稳定版发布后显著改善您的 Python 工作流。下面就来概述这些新特性。
1. 速度提升
首先让数据科学家兴奋的重大变化是速度提升——标准基准测试套件相较 3.10 大约快了 25%。官方文档称,在某些情况下 3.11 最高可快 60%。下面介绍如何自己执行基准测试,以验证速度提升。
要比较 Python 3.10 与 3.11 的速度,您需要安装 Docker 。确认 Docker Desktop 正在运行后,在终端中执行以下两条命令,它们会为两个 Python 版本各自下载一个镜像。
$ docker run -d python:3.10.4-bullseye
$ docker run -d python:3.11-rc-bullseye技术支持
下载完成的镜像应可在您的 Docker 仪表盘中看到,您也可以在此启动它们。
启动容器后,您可以运行 docker ps 查看容器 ID、镜像、状态等详细信息。
运行中的容器也会显示在仪表盘的 Containers 选项卡下,您会在“Run/Stop”旁看到 CLI 按钮。为两个容器都点击该按钮,以启动分别附着在容器上的两个终端标签页。
在两个标签页中,都通过 pip 安装 pyperformance 包。然后在各自容器的终端中运行下面的命令。
针对 Python 3.10
$ pyperformance run -r -o py310.json技术支持
针对 Python 3.11
$ pyperformance run -r -o py310.jsone run -r -o py311.json技术支持
这些命令会对标准库中的约 60 个 Python 函数运行基准测试,并生成 JSON 元数据。我可选地添加了 -r 标签,告诉 pyperformance 我希望测试更为严格,这将更耗时。在我的案例中,两个容器运行在一台搭载 AMD Ryzen 12 核 CPU 的 Windows 机器上。
现在两个容器中各有一个 JSON 文件,我们需要把它们放到同一目录中以继续进行速度测试。为此,我们使用 docker cp 命令将 Python 3.11 容器中的 JSON 文件复制到 3.10 容器中。
在单独的终端标签页中运行以下命令,并根据您计算机上的实际路径进行更新:
$ docker cp crazy_snyder:/py311.json C:/Users/bex/Desktop
$ docker cp C:/Users/bex/Desktop/py311.json charming_proskuriakova:/技术支持
在我的例子中,crazy_snyder 和 charming_proskuriakova 是正在运行的容器 ID。现在两个 JSON 文件都在 Python 3.10 容器中。要完成基准测试并将结果保存为 CSV,请运行以下命令。
$ pyperformance compare py310.json py311.json --csv comparison.csv
$ docker cp charming_proskuriakova:/comparison.csv C:/Users/bex/Desktop/articles技术支持
最后,我们将 CSV 加载到 Pandas 中进行分析:
import matplotlib. pyplot as plt
import pandas as pd
import seaborn as sns
df = pd. read_csv( "data/comparison.csv" )
df. rename( { "Base" : "py310" , "Changed" : "py311" , "Benchmark" : "function" } ,
axis= 1 ,
inplace= True ) 技术支持
>> > df. shape
技术支持
(59, 3)技术支持
>> > df. sample( 5 )
技术支持
Function py310 py311 40 scimark_monte_carlo0.12392 0.08052 19 mako0.01967 0.01289 1 chameleon0.01131 0.00843 8 float0.14265 0.09133 35 regex_effbot0.00315 0.00261
数据框中的每一行都记录了两个版本运行给定 Python 函数所耗费的时间(毫秒)。我们来绘制速度提升的直方图。
df[ "speed_up" ] = ( df[ "py310" ] / df[ "py311" ] ) . round ( 3 )
fig, ax = plt. subplots( )
sns. histplot( df[ "speed_up" ] , bins= 11 )
ax. set ( xlabel= "Speedup (times)" ,
title= "Python 3.10 vs. Python 3.11 - speedup comparison" )
plt. show( ) 技术支持
从图中可以明显看出,Python 3.11 中大多数函数大约快了 1.2 倍(20%)。我们也可以用均值和中位数来验证这一估计。
>> > df[ "speed_up" ] . mean( )
技术支持
1.2605593220338982技术支持
>> > df[ "speed_up" ] . median( )
技术支持
1.207技术支持
看起来有一个案例的速度提升超过了 60%。
>> > df[ "speed_up" ] . max ( )
技术支持
1.899技术支持
同时也有四个案例显示 Python 3.10 比新版本更快。
>> > ( df[ "speed_up" ] <= 1 ) . sum ( )
技术支持
4技术支持
虽然纸面上的性能提升显而易见,但其具体影响会因人而异,而且 Python 3.11 的最终稳定版尚未发布。该基准测试使用的是纯 Python 函数,您在日常工作中可能并不会大量使用。不过,同时为 Python 3.10 与 3.11 搭建 Docker 环境,仍能帮助您评估针对自身用例的速度提升情况。
2. 更好的错误消息
Python 3.11 另一项令人期待的特性是更精准的错误提示,它能指出错误的准确位置。相比返回长达百行、且末尾错误信息难以理解的 traceback,Python 3.11 会定位到导致错误的那个具体表达式。
在上面的示例中,解释器指出由于值为 None 的 x 导致脚本崩溃。在当前版本的 Python 中,错误会比较模糊,因为有两个对象都带有“x”属性。而 3.11 的错误处理则清楚地指出了有问题的表达式。
这个例子展示了 3.11 如何从深层嵌套的字典中定位错误,并清晰地标出出错的键属于哪一层。
在复杂的算术表达式中,同样能看到这种精确度。
更新后的错误消息无疑是令人欢迎的补充,尤其能帮助在调试脚本上费力的数据科学家。
3. 异常备注(Exception Notes)
“清晰优于隐晦。”
上面这句话是Python 之禅 的第二条准则,这 20 条设计原则之一强调 Python 代码应当尽可能表达清晰。
为强化这一设计理念,Python 3.11 引入了异常备注(PEP 678 )。现在,在 except 子句中,您可以调用 add_note() 函数,在抛出错误时附加自定义消息。
import math
try :
math. sqrt( - 1 )
except ValueError as e:
e. add_note( "Negative value passed! Please try again." )
raise 技术支持
如果您像下面这样编写了自定义异常类,也可以在受保护的类级属性 __notes__ 中为该类添加多条备注:
import math
class MyOwnError ( Exception) :
__notes__ = [ "This is a custom error!" ]
try :
math. sqrt( - 1 )
except :
raise MyOwnError技术支持
现在,当解释器触发该错误时,会在常规消息体之后显示自定义消息。
此外,还引入了与新类 ExceptionGroup 搭配使用的 except* 子句语法。PEP 654 表示,在多种场景中可以用它同时抛出多个相互无关的错误。多数此类场景较为小众,例如处理 WebSocket、使用 asyncio 进行并发编程等,在日常数据科学工作中并不常见。如果您感兴趣,可以在此处 了解新语法。
4. 新的类型特性:Self
静态类型有助于提升代码的可读性与可调试性。明确变量、函数输入与输出的具体类型,能帮您节省数小时的调试时间,也让他人更容易阅读您的代码。添加类型注解还能让现代 IDE 在您输入函数名时显示函数定义,便于他人理解您的函数。
此前,Python 中强大的 typing 模块 几乎为所有数据类型提供了类,唯独缺少“返回自身实例”的类。在当前版本的 Python 中,下面的示例是无法实现的:
from typing import Self
class Language :
def __init__ ( self, name, version, release_date) :
self. name = name
self. version = version
self. release_date = release_date
def change_version ( self, version) - > Self:
self. version = version
return Language( self. name, self. version, self. release_date) 技术支持
而在 Python 3.11 中,引入了 Self 类。如果函数的返回值是 self 或该类的新实例,您就可以在函数定义中使用 Self。
5. 标准库的改进
标准库还有一些其他的易用性改进。首先,math 模块新增了两个期待已久的函数。
>> > import math
>> > math. cbrt( 9 )
2.080083823051904
>> > math. cbrt( 27 )
3.0000000000000004
>> > math. exp2( 5 )
32.0 技术支持
立方根函数竟然让 Python 等了 28 年才加入,确实令人惊讶,但俗话说得好,“亡羊补牢,犹未为晚”。
fractions 模块也新增了一个功能,允许您从字符串创建分数:
>> > from fractions import Fraction
>> > Fraction( "22/7" )
Fraction( 22 , 7 )
>> > Fraction( numerator= 22 , denominator= 7 )
Fraction( 22 , 7 )
>> > Fraction( "3e-4" )
Fraction( 3 , 10000 )
>> > Fraction( "-73/41" )
Fraction( - 73 , 41 )
>> > Fraction( 3.1415 )
Fraction( 7074029114692207 , 2251799813685248 ) 技术支持
如您所见,fractions 模块在某些算术运算中相当实用。我尤其喜欢它能找到最接近给定浮点数的分数。您还可以进一步通过设置分母上限来控制:
>> > from math import pi
>> > Fraction( pi) . limit_denominator( 100000 )
Fraction( 312689 , 99532 ) 技术支持
此外,还新增了用于解析 TOML 文档的 tomllib 模块。TOML(Tom's Obvious Minimal Language)是一种用于编写人类可读配置文件的流行格式。下面这张图来自项目主页 :
import tomllib
toml_str = """
python-version = "3.11.0"
release_date = "2022-10-22"
"""
data = tomllib. loads( toml_str)
print ( data)
print ( data[ 'python-version' ] )
print ( data[ 'release_date' ] ) 技术支持
Python 3.11 的发布时间
Python 3.11 的开发始于 2021 年 5 月 5 日。此后发布了七个 alpha 版本,并于 2022 年 5 月 8 日首次推出 beta 版。从该日期起直到正式发布,Python 将不再引入新功能。
最终的稳定版将于 2022 年 10 月 3 日发布,其间还会有三个 beta 版与两个候选版本。想要进一步了解 Python,您可以查看以下资源。
在过去四年里,Python 三次获得 TIOBE “年度语言” 奖项,四年中的三次都由它摘得。到 2022 年年中,这门广受欢迎的编程语言依然位居 TIOBE 指数榜首。
Python 位居 2022 年 6 月 TIOBE 指数榜首。
Python 的评分为 12.74%,意味着关键词“Python”出现在大约 13% 的所有编程相关搜索引擎查询中。换句话说,互联网上每 7 到 8 个编程问题中就有一个与 Python 有关。
如今,Python 经常与数据科学和人工智能领域的重大突破相伴。实践者看重它的简洁、覆盖多种任务的大量内置与第三方库,以及强大的社区。
随着 3.11 的最终稳定版将在 2022 年 10 月 3 日发布,Python 社区可以期待多项令人欢迎的更新,包括显著的速度提升、更好的错误处理与调试能力,以及对标准库的诸多易用性改进。
Python 3.11 有哪些新功能?
Python 3.11 更新日志几乎是无尽的修复、改进与新增条目清单,其中大多数您可能甚至不会注意到。不过,有几项关键的新功能可能会在稳定版发布后显著改善您的 Python 工作流。下面就来概述这些新特性。
1. 速度提升
首先让数据科学家兴奋的重大变化是速度提升——标准基准测试套件相较 3.10 大约快了 25%。官方文档称,在某些情况下 3.11 最高可快 60%。下面介绍如何自己执行基准测试,以验证速度提升。
要比较 Python 3.10 与 3.11 的速度,您需要安装 Docker。确认 Docker Desktop 正在运行后,在终端中执行以下两条命令,它们会为两个 Python 版本各自下载一个镜像。
下载完成的镜像应可在您的 Docker 仪表盘中看到,您也可以在此启动它们。
启动容器后,您可以运行 docker ps 查看容器 ID、镜像、状态等详细信息。
运行中的容器也会显示在仪表盘的 Containers 选项卡下,您会在“
Run/Stop”旁看到 CLI 按钮。为两个容器都点击该按钮,以启动分别附着在容器上的两个终端标签页。在两个标签页中,都通过
pip安装pyperformance包。然后在各自容器的终端中运行下面的命令。针对 Python 3.10
针对 Python 3.11
这些命令会对标准库中的约 60 个 Python 函数运行基准测试,并生成 JSON 元数据。我可选地添加了
-r标签,告诉pyperformance我希望测试更为严格,这将更耗时。在我的案例中,两个容器运行在一台搭载 AMD Ryzen 12 核 CPU 的 Windows 机器上。现在两个容器中各有一个 JSON 文件,我们需要把它们放到同一目录中以继续进行速度测试。为此,我们使用
docker cp命令将 Python 3.11 容器中的 JSON 文件复制到 3.10 容器中。在单独的终端标签页中运行以下命令,并根据您计算机上的实际路径进行更新:
在我的例子中,
crazy_snyder和charming_proskuriakova是正在运行的容器 ID。现在两个 JSON 文件都在 Python 3.10 容器中。要完成基准测试并将结果保存为 CSV,请运行以下命令。最后,我们将 CSV 加载到 Pandas 中进行分析:
scimark_monte_carlomakochameleonfloatregex_effbot数据框中的每一行都记录了两个版本运行给定 Python 函数所耗费的时间(毫秒)。我们来绘制速度提升的直方图。
从图中可以明显看出,Python 3.11 中大多数函数大约快了 1.2 倍(20%)。我们也可以用均值和中位数来验证这一估计。
看起来有一个案例的速度提升超过了 60%。
同时也有四个案例显示 Python 3.10 比新版本更快。
虽然纸面上的性能提升显而易见,但其具体影响会因人而异,而且 Python 3.11 的最终稳定版尚未发布。该基准测试使用的是纯 Python 函数,您在日常工作中可能并不会大量使用。不过,同时为 Python 3.10 与 3.11 搭建 Docker 环境,仍能帮助您评估针对自身用例的速度提升情况。
2. 更好的错误消息
Python 3.11 另一项令人期待的特性是更精准的错误提示,它能指出错误的准确位置。相比返回长达百行、且末尾错误信息难以理解的 traceback,Python 3.11 会定位到导致错误的那个具体表达式。
在上面的示例中,解释器指出由于值为 None 的 x 导致脚本崩溃。在当前版本的 Python 中,错误会比较模糊,因为有两个对象都带有“x”属性。而 3.11 的错误处理则清楚地指出了有问题的表达式。
这个例子展示了 3.11 如何从深层嵌套的字典中定位错误,并清晰地标出出错的键属于哪一层。
在复杂的算术表达式中,同样能看到这种精确度。
更新后的错误消息无疑是令人欢迎的补充,尤其能帮助在调试脚本上费力的数据科学家。
3. 异常备注(Exception Notes)
“清晰优于隐晦。”
上面这句话是Python 之禅的第二条准则,这 20 条设计原则之一强调 Python 代码应当尽可能表达清晰。
为强化这一设计理念,Python 3.11 引入了异常备注(PEP 678)。现在,在 except 子句中,您可以调用
add_note()函数,在抛出错误时附加自定义消息。如果您像下面这样编写了自定义异常类,也可以在受保护的类级属性
__notes__中为该类添加多条备注:现在,当解释器触发该错误时,会在常规消息体之后显示自定义消息。
此外,还引入了与新类 ExceptionGroup 搭配使用的 except* 子句语法。PEP 654 表示,在多种场景中可以用它同时抛出多个相互无关的错误。多数此类场景较为小众,例如处理 WebSocket、使用
asyncio进行并发编程等,在日常数据科学工作中并不常见。如果您感兴趣,可以在此处了解新语法。4. 新的类型特性:Self
静态类型有助于提升代码的可读性与可调试性。明确变量、函数输入与输出的具体类型,能帮您节省数小时的调试时间,也让他人更容易阅读您的代码。添加类型注解还能让现代 IDE 在您输入函数名时显示函数定义,便于他人理解您的函数。
此前,Python 中强大的 typing 模块几乎为所有数据类型提供了类,唯独缺少“返回自身实例”的类。在当前版本的 Python 中,下面的示例是无法实现的:
而在 Python 3.11 中,引入了 Self 类。如果函数的返回值是 self 或该类的新实例,您就可以在函数定义中使用 Self。
5. 标准库的改进
标准库还有一些其他的易用性改进。首先,math 模块新增了两个期待已久的函数。
立方根函数竟然让 Python 等了 28 年才加入,确实令人惊讶,但俗话说得好,“亡羊补牢,犹未为晚”。
fractions 模块也新增了一个功能,允许您从字符串创建分数:
如您所见,fractions 模块在某些算术运算中相当实用。我尤其喜欢它能找到最接近给定浮点数的分数。您还可以进一步通过设置分母上限来控制:
此外,还新增了用于解析 TOML 文档的
tomllib模块。TOML(Tom's Obvious Minimal Language)是一种用于编写人类可读配置文件的流行格式。下面这张图来自项目主页:Python 3.11 的发布时间
Python 3.11 的开发始于 2021 年 5 月 5 日。此后发布了七个 alpha 版本,并于 2022 年 5 月 8 日首次推出 beta 版。从该日期起直到正式发布,Python 将不再引入新功能。
最终的稳定版将于 2022 年 10 月 3 日发布,其间还会有三个 beta 版与两个候选版本。想要进一步了解 Python,您可以查看以下资源。