Python 3.7 的新特性 — Python 文档

来自菜鸟教程
Python/docs/3.9/whatsnew/3.7
跳转至:导航、​搜索

Python 3.7 中的新功能

编辑
埃尔维斯·普兰斯克维奇 < 猫王@magic.io >

本文解释了 Python 3.7 中与 3.6 相比的新特性。 Python 3.7 于 2018 年 6 月 27 日发布。 有关完整详细信息,请参阅 变更日志

摘要 – 发布亮点

新的语法特性:

  • PEP 563,推迟了对类型注释的评估。

向后不兼容的语法更改:

新的库模块:

新的内置功能:

Python 数据模型改进:

标准库的重大改进:

CPython 实现改进:

C API 改进:

  • PEP 539,用于线程本地存储的新 C API

文档改进:

此版本在许多方面都有显着的性能改进。 Optimizations 部分详细列出了它们。

有关可能影响与以前 Python 版本兼容性的更改列表,请参阅 移植到 Python 3.7 部分。


新特性

PEP 563:推迟评估注释

Python 中类型提示的出现揭示了两个明显的可用性问题,即在 PEP 3107 中添加并在 PEP 526[X19X] 中进一步完善的注释功能]:

  • 注释只能使用在当前范围内已经可用的名称,换句话说,它们不支持任何类型的前向引用; 和
  • 注释源代码对 Python 程序的启动时间有不利影响。

通过推迟对注释的评估,这两个问题都得到了解决。 编译器不是在定义时编译在注释中执行表达式的代码,而是将注释存储为字符串形式,相当于所讨论的表达式的 AST。 如果需要,可以在运行时使用 typing.get_type_hints() 解析注释。 在不需要这样做的常见情况下,注释的存储成本更低(因为短字符串由解释器驻留)并缩短启动时间。

可用性方面,注释现在支持前向引用,使以下语法有效:

class C:
    @classmethod
    def from_string(cls, source: str) -> C:
        ...

    def validate_b(self, obj: B) -> bool:
        ...

class B:
    ...

由于此更改破坏了兼容性,因此需要在 Python 3.7 中使用 __future__ 导入在每个模块的基础上启用新行为:

from __future__ import annotations

它将成为 Python 3.10 中的默认值。

也可以看看

PEP 563 – 注释的推迟评估
PEP 由 Łukasz Langa 编写和实施。


PEP 538:传统 C 语言环境强制

Python 3 系列中的一个持续挑战是确定一种合理的默认策略,用于处理当前由在非 Windows 平台上使用默认 C 或 POSIX 语言环境所隐含的“7 位 ASCII”文本编码假设。

PEP 538 更新了默认解释器命令行界面,以自动将该语言环境强制转换为可用的基于 UTF-8 的语言环境,如新的 [X206X 的文档中所述]PYTHONCOERCECLOCALE 环境变量。 以这种方式自动设置 LC_CTYPE 意味着核心解释器和区域设置感知 C 扩展(例如 readline)将假定使用 UTF-8 作为默认文本编码,而不是 ASCII .

PEP 11 中的平台支持定义也已更新,以将全文处理支持限制为适当配置的基于非 ASCII 的语言环境。

作为此更改的一部分,stdinstdout 的默认错误处理程序在使用任何已定义的强制目标语言环境(当前为 C.UTF-8C.utf8UTF-8)。 stderr 的默认错误处理程序仍然是 backslashreplace,无论语言环境如何。

默认情况下,语言环境强制是静默的,但为了帮助调试潜在的语言环境相关的集成问题,可以通过设置 PYTHONCOERCECLOCALE=warn 来请求显式警告(直接在 stderr 上发出)。 如果在核心解释器初始化时遗留 C 语言环境保持活动状态,此设置还将导致 Python 运行时发出警告。

虽然 PEP 538 的区域设置强制也有影响扩展模块(例如 GNU readline)以及子进程(包括那些运行非Python 应用程序和旧版本的 Python),它的缺点是要求在运行的系统上存在合适的目标语言环境。 为了更好地处理没有合适的目标语言环境可用的情况(例如在 RHEL/CentOS 7 上发生的情况),Python 3.7 还实现了 PEP 540:强制 UTF-8 运行时模式

也可以看看

PEP 538 – 将传统 C 语言环境强制转换为基于 UTF-8 的语言环境
PEP 由 Nick Coghlan 编写和实施。


PEP 540:强制 UTF-8 运行时模式

新的 -X utf8 命令行选项和 PYTHONUTF8 环境变量可用于启用 CPython UTF-8 模式[ X152X]。

在 UTF-8 模式下,CPython 会忽略区域设置,并默认使用 UTF-8 编码。 sys.stdinsys.stdout 流的错误处理程序设置为 surrogateescape

强制 UTF-8 模式可用于更改嵌入式 Python 解释器中的文本处理行为,而无需更改嵌入应用程序的区域设置。

尽管 PEP 540 的 UTF-8 模式的优点是无论运行系统上有哪些区域设置都可以工作,但它的缺点是对扩展模块(例如作为 GNU readline)、运行非 Python 应用程序的子进程和运行旧版本 Python 的子进程。 为了降低与此类组件通信时损坏文本数据的风险,Python 3.7 还实现了 PEP 540:强制 UTF-8 运行时模式 )。

当语言环境为 CPOSIX 时默认启用 UTF-8 模式,并且 PEP 538 语言环境强制功能无法更改它到基于 UTF-8 的替代方案(无论失败是由于设置了 PYTHONCOERCECLOCALE=0、设置了 LC_ALL,还是缺少合适的目标语言环境)。

也可以看看

PEP 540 – 添加新的 UTF-8 模式
PEP 由 Victor Stinner 编写和实施


PEP 553:内置 breakpoint()

Python 3.7 包含新的内置 breakpoint() 函数,作为进入 Python 调试器的一种简单且一致的方式。

内置 breakpoint() 调用 sys.breakpointhook()。 默认情况下,后者导入pdb,然后调用pdb.set_trace(),但是通过将sys.breakpointhook()绑定到您选择的函数,breakpoint()可以进入任何调试器。 此外,环境变量 PYTHONBREAKPOINT 可以设置为您选择的调试器的可调用对象。 设置PYTHONBREAKPOINT=0完全禁用内置breakpoint()

也可以看看

PEP 553 – 内置断点()
由 Barry Warsaw 编写和实施的 PEP


PEP 539:用于线程本地存储的新 C API

虽然 Python 为线程本地存储支持提供了 C API; 现有的 线程本地存储 (TLS) API 已使用 int 来表示所有平台上的 TLS 密钥。 对于官方支持的平台来说,这通常不是问题,但这既不符合 POSIX 标准,也不符合任何实际意义上的可移植性。

PEP 539 通过向 CPython 提供新的 线程特定存储 (TSS) API 来改变这一点,该 API 取代了在 CPython 解释器中使用现有的 TLS API,同时弃用现有的 API。 TSS API 使用新类型 Py_tss_t 而不是 int 来表示 TSS 密钥——一种不透明类型,其定义可能取决于底层 TLS 实现。 因此,这将允许在本地 TLS 密钥以无法安全转换为 int 的方式定义的平台上构建 CPython。

请注意,在以无法安全地转换为 int 的方式定义本机 TLS 密钥的平台上,现有 TLS API 的所有功能都将是空操作并立即返回失败。 这清楚地表明旧 API 在不能可靠使用的平台上不受支持,并且不会努力添加此类支持。

也可以看看

PEP 539 – CPython 中用于线程本地存储的新 C-API
PEP 由 Erik M. 嘶叫; 由山本雅之实施。


PEP 562:自定义访问模块属性

Python 3.7 允许在模块上定义 __getattr__(),并在找不到模块属性时调用它。 现在也允许在模块上定义 __dir__()

这可能有用的一个典型例子是模块属性弃用和延迟加载。

也可以看看

PEP 562 – 模块 __getattr____dir__
PEP 由 Ivan Levkivskyi 编写和实施


PEP 564:具有纳秒分辨率的新时间函数

现代系统中时钟的分辨率可能超过 time.time() 函数及其变体返回的浮点数的有限精度。 为避免精度损失,PEP 564time 模块添加了现有计时器函数的六个新的“纳秒”变体:

新函数将纳秒数作为整数值返回。

Measurements 表明,在 Linux 和 Windows 上,time.time_ns() 的分辨率大约比 time.time() 的分辨率好 3 倍。

也可以看看

PEP 564 – 添加具有纳秒分辨率的新时间函数
PEP 由 Victor Stinner 编写和实施


PEP 565:在 __main__ 中显示弃用警告

DeprecationWarning 的默认处理已更改,这些警告在默认情况下再次显示,但仅当触发它们的代码直接在 __main__ 模块中运行时。 因此,单文件脚本的开发人员和交互式使用 Python 的开发人员应该再次开始看到他们使用的 API 的弃用警告,但默认情况下,由导入的应用程序、库和框架模块触发的弃用警告将继续隐藏。

由于此更改,标准库现在允许开发人员在三种不同的弃用警告行为之间进行选择:

  • FutureWarning:默认情况下始终显示,推荐用于应用程序最终用户看到的警告(例如 对于已弃用的应用程序配置设置)。
  • DeprecationWarning:默认情况下仅显示在 __main__ 和运行测试时,推荐用于其他 Python 开发人员看到的警告,其中版本升级可能导致行为改变或错误。
  • PendingDeprecationWarning:仅在运行测试时默认显示,用于未来版本升级将警告类别更改为 DeprecationWarningFutureWarning 的情况。

以前,DeprecationWarningPendingDeprecationWarning 仅在运行测试时可见,这意味着主要编写单文件脚本或交互式使用 Python 的开发人员可能会对他们使用的 API 中的重大更改感到惊讶。

也可以看看

PEP 565 – 在 __main__ 中显示弃用警告
PEP 由 Nick Coghlan 编写和实施


PEP 560:对 typing 模块和泛型类型的核心支持

最初 PEP 484 的设计方式是不会对核心 CPython 解释器引入 任何 更改。 现在输入提示和 typing 模块被社区广泛使用,所以这个限制被删除了。 PEP 引入了两个特殊方法 __class_getitem__()__mro_entries__,这些方法现在被 typing 中的大多数类和特殊构造使用。 因此,类型的各种操作的速度提高了 7 倍,可以使用泛型类型而不会发生元类冲突,并且修复了 typing 模块中的几个长期存在的错误。

也可以看看

PEP 560 – 对输入模块和泛型类型的核心支持
PEP 由 Ivan Levkivskyi 编写和实施


PEP 552:基于哈希的 .pyc 文件

Python 传统上通过比较源元数据(最后修改的时间戳和大小)与缓存文件头中保存的源元数据来检查字节码缓存文件(即 .pyc 文件)的最新性。生成。 虽然有效,但这种失效方法有其缺点。 当文件系统时间戳太粗糙时,Python 可能会错过源更新,导致用户混淆。 此外,缓存文件中的时间戳对于 构建重现性 和基于内容的构建系统来说是有问题的。

PEP 552 扩展了 pyc 格式,允许使用源文件的哈希值而不是源时间戳来进行失效。 这样的 .pyc 文件被称为“基于哈希的”。 默认情况下,Python 仍然使用基于时间戳的失效,并且不会在运行时生成基于哈希的 .pyc 文件。 可以使用 py_compilecompileall 生成基于哈希的 .pyc 文件。

基于哈希的 .pyc 文件有两种变体:已选中和未选中。 Python 在运行时根据相应的源文件验证已检查的基于哈希的 .pyc 文件,但不会对未检查的基于哈希的 pyc 进行验证。 未经检查的基于散列的 .pyc 文件对于 Python 外部系统(例如构建系统)负责使 .pyc 文件保持最新的环境是一种有用的性能优化。

有关更多信息,请参阅 缓存字节码失效

也可以看看

PEP 552 – 确定性 pycs
由 Benjamin Peterson 编写和实施的 PEP


PEP 545:Python 文档翻译

PEP 545 描述了创建和维护 Python 文档翻译的过程。

添加了三个新的翻译:

也可以看看

PEP 545 – Python 文档翻译
PEP 由 Julien Palard、Inada Naoki 和 Victor Stinner 编写和实施。


Python 开发模式 (-X dev)

新的 -X dev 命令行选项或新的 PYTHONDEVMODE 环境变量可用于启用 Python 开发模式 ]。 在开发模式下,Python 会执行额外的运行时检查,这些检查的成本太高而无法默认启用。 有关完整说明,请参阅 Python 开发模式 文档。


其他语言更改


新模块

上下文变量

新的 contextvars 模块和一组 新的 C API 引入了对 上下文变量 的支持。 上下文变量在概念上类似于线程局部变量。 与 TLS 不同,上下文变量正确支持异步代码。

asynciodecimal 模块已更新为使用和支持开箱即用的上下文变量。 特别是活动的十进制上下文现在存储在上下文变量中,它允许十进制操作与异步代码中的正确上下文一起工作。

也可以看看

PEP 567 – 上下文变量
由 Yury Selivanov 编写和实施的 PEP


数据类

新的 dataclass() 装饰器提供了一种声明 数据类 的方法。 数据类使用类变量注释来描述其属性。 它的构造函数和其他魔法方法,如 __repr__()__eq__()__hash__() 都是自动生成的。

例子:

@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0

p = Point(1.5, 2.5)
print(p)   # produces "Point(x=1.5, y=2.5, z=0.0)"

也可以看看

PEP 557 – 数据类
PEP 由 Eric V 编写和实施。 史密斯


导入lib.resources

新的 importlib.resources 模块提供了几个新的 API 和一个新的 ABC,用于访问、打开和读取包内的 resources。 资源大致类似于包内的文件,但它们不必是物理文件系统上的实际文件。 模块加载器可以提供一个 get_resource_reader() 函数,它返回一个 importlib.abc.ResourceReader 实例来支持这个新的 API。 内置文件路径加载器和 zip 文件加载器都支持这一点。

由 Barry Warsaw 和 Brett Cannon 在 中贡献:issue:`32248`

也可以看看

importlib_resources – 早期 Python 版本的 PyPI 向后移植。


改进的模块

参数解析

新的 ArgumentParser.parse_intermixed_args() 方法允许混合选项和位置参数。 (由 paul.j3 在 :issue:`14191` 中提供。)


异步

asyncio 模块获得了许多新功能、可用性和 性能改进 。 显着的变化包括:

几个 asyncio API 已被 弃用


二进制文件

b2a_uu() 函数现在接受一个可选的 backtick 关键字参数。 当它为真时,零由 '`' 而不是空格表示。 (由 Zhang 在 中提供:issue:`30103`。)


日历

HTMLCalendar 类具有新的类属性,可以简化生成的 HTML 日历中 CSS 类的自定义。 (由 Oz Tiram 在 中提供:issue:`30095`。)


收藏

collections.namedtuple() 现在支持默认值。 (由 Raymond Hettinger 在 中提供:issue:`32320`。)


编译所有

compileall.compile_dir() 学习了新的 invalidation_mode 参数,可用于启用 基于哈希的 .pyc 失效。 也可以使用新的 --invalidation-mode 参数在命令行上指定失效模式。 (由 Benjamin Peterson 在 中提供:issue:`31650`。)


并发期货

ProcessPoolExecutorThreadPoolExecutor 现在支持新的 initializerinitargs 构造函数参数。 (由 Antoine Pitrou 在 中提供:issue:`21423`。)

ProcessPoolExecutor 现在可以通过新的 mp_context 参数获取多处理上下文。 (由 Thomas Moreau 在 中提供:issue:`31540`。)


上下文库

新的 nullcontext() 是比 ExitStack 更简单、更快的无操作上下文管理器。 (由 Jesse-Bakker 在 :issue:`10049` 中贡献。)

添加了新的 asynccontextmanager()AbstractAsyncContextManagerAsyncExitStack 以补充它们的同步对应项。 (由 Jelle Zijlstra 在 :issue:`29679`:issue:`30241` 以及 Alexander Mohr 和 Ilya Kulakov 在 :issue:`29302`[ X147X]。)


个人资料

cProfile 命令行现在接受 -m module_name 作为脚本路径的替代。 (由 Sanyam Khurana 在 :issue:`21862` 中提供。)


地穴

crypt 模块现在支持 Blowfish 哈希方法。 (由 Serhiy Storchaka 在 中提供:issue:`31664`。)

mksalt() 函数现在允许指定散列的轮数。 (由 Serhiy Storchaka 在 中提供:issue:`31702`。)


约会时间

新的 datetime.fromisoformat() 方法根据 datetime.isoformat() 输出格式之一的字符串构造 datetime 对象。 (由 Paul Ganssle 在 :issue:`15873` 中提供。)

tzinfo 类现在支持亚分钟偏移量。 (由 Alexander Belopolsky 在 :issue:`5288` 中贡献。)


数据库

dbm.dumb 现在支持读取只读文件,不再写入未更改的索引文件。


十进制

decimal 模块现在使用 context variables 来存储十进制上下文。 (由 Yury Selivanov 在 :issue:`32630` 中贡献。)


迪斯

dis() 函数现在能够反汇编嵌套代码对象(推导式、生成器表达式和嵌套函数的代码,以及用于构建嵌套类的代码)。 反汇编递归的最大深度由新的 depth 参数控制。 (由 Serhiy Storchaka 在 中提供:issue:`11822`。)


分配器

README.rst 现在包含在 distutils 标准自述文件列表中,因此包含在源代码分发中。 (由 Ryan Gonzalez 在 中提供:issue:`11913`。)


枚举

Enum 学习了新的 _ignore_ 类属性,它允许列出不应成为枚举成员的属性的名称。 (由 Ethan Furman 在 中提供:issue:`31801`。)

在 Python 3.8 中,尝试检查 Enum 类中的非 Enum 对象将引发 TypeError(例如 1 in Color); 类似地,尝试检查 Flag 成员中的非标志对象将引发 TypeError(例如 1 in Perm.RW); 目前,这两个操作都返回 False 并且已弃用。 (由 Ethan Furman 在 中提供:issue:`33217`。)


功能工具

functools.singledispatch() 现在支持使用类型注释注册实现。 (由 Łukasz Langa 在 中提供:issue:`32227`。)


GC

新的 gc.freeze() 函数允许冻结垃圾收集器跟踪的所有对象,并将它们从未来的收集中排除。 这可以在 POSIX fork() 调用之前使用,以使 GC 写时复制友好或加快收集速度。 新的 gc.unfreeze() 函数反转了这个操作。 此外,gc.get_freeze_count() 可用于获取冻结对象的数量。 (由李泽坤在 中提供:issue:`31558`。)


海马

hmac 模块现在有一个优化的一次性 digest() 函数,比 HMAC() 快三倍。 (由 Christian Heimes 在 中提供:issue:`32433`。)


客户端

HTTPConnectionHTTPSConnection 现在支持新的 blocksize 参数以提高上传吞吐量。 (由 Nir Soffer 在 中提供:问题:`31945`。)


http.server

SimpleHTTPRequestHandler 现在支持 HTTP If-Modified-Since 标头。 如果在标头中指定的时间之后没有修改目标文件,则服务器返回 304 响应状态。 (由 Pierre Quentel 在 中提供:issue:`29654`。)

SimpleHTTPRequestHandler 除了新的 --directory 命令行参数之外,还接受新的 directory 参数。 使用此参数,服务器为指定目录提供服务,默认情况下它使用当前工作目录。 (由 Stéphane Wirtel 和 Julien Palard 在 :issue:`28707` 中提供。)

新的 ThreadingHTTPServer 类使用线程来处理使用 ThreadingMixin 的请求。 当 http.server-m 一起运行时使用。 (由 Julien Palard 在 中提供:issue:`31639`。)


空闲库和空闲

自动完成的多项修复。 (由 Louie Lu 在 中提供:issue:`15786`。)

模块浏览器(在文件菜单上,以前称为类浏览器)现在除了显示顶级函数和类之外,还显示嵌套的函数和类。 (由 Guilherme Polo、Cheryl Sabella 和 Terry Jan Reedy 在 :issue:`1612262` 中提供。)

设置对话框(选项、配置空闲)已部分重写以改进外观和功能。 (由 Cheryl Sabella 和 Terry Jan Reedy 在多个问题中提供。)

字体示例现在包括一系列非拉丁字符,以便用户可以更好地看到选择特定字体的效果。 (由 Terry Jan Reedy 在 中贡献:issue:`13802`。)可以编辑示例以包含其他字符。 (由 Serhiy Storchaka 在 中提供:issue:`31860`。)

以前作为扩展实现的 IDLE 功能已重新实现为普通功能。 它们的设置已从“扩展”选项卡移至其他对话框选项卡。 (由 Charles Wohlganger 和 Terry Jan Reedy 在 :issue:`27099` 中提供。)

修改了编辑器代码上下文选项。 Box 显示所有上下文行直到 maxlines。 单击上下文行会将编辑器跳转到该行。 自定义主题的上下文颜色添加到“设置”对话框的“亮点”选项卡中。 (由 Cheryl Sabella 和 Terry Jan Reedy 在 :issue:`33642`:issue:`33768`:issue:`33679` 中贡献。 )

在 Windows 上,一个新的 API 调用告诉 Windows tk 针对 DPI 进行缩放。 在 Windows 8.1+ 或 10 上,Python 二进制文件的 DPI 兼容性属性保持不变,并且显示器分辨率大于 96 DPI,这应该会使文本和线条更清晰。 否则它应该没有任何影响。 (由 Terry Jan Reedy 在 :issue:`33656` 中提供。)

3.7.1 中的新功能:

N 行(默认为 50)的输出被压缩到一个按钮。 N 可以在 Settings 对话框的 General 页面的 PyShell 部分中更改。 右键单击输出可以压缩更少但可能超长的行。 可以通过双击按钮或右键单击按钮将压缩的输出扩展到剪贴板或单独的窗口。 (由 Tal Einat 在 中提供:问题:`1529353`。)

上述更改已向后移植到 3.6 维护版本。

3.7.4 中的新功能:

将“运行自定义”添加到“运行”菜单以运行具有自定义设置的模块。 输入的任何命令行参数都会添加到 sys.argv。 它们重新出现在框中以供下一次自定义运行。 还可以抑制正常的Shell主模块重启。 (由 Cheryl Sabella、Terry Jan Reedy 和其他人在 :issue:`5680`:issue:`37627` 中贡献。)

3.7.5 中的新功能:

为空闲编辑器窗口添加可选的行号。 除非在配置对话框的“常规”选项卡中进行了其他设置,否则 Windows 将在没有行号的情况下打开。 现有窗口的行号在选项菜单中显示和隐藏。 (由 Tal Einat 和 Saimadhav Heblikar 在 :issue:`17535` 中提供。)


导入库

引入了 importlib.abc.ResourceReader ABC 以支持从包中加载资源。 另见 importlib.resources。 (由 Barry Warsaw、Brett Cannon 在 中提供:issue:`32248`。)

importlib.reload() 现在如果模块缺少规范会引发 ModuleNotFoundError。 (由 Garvit Khatri 在 中提供:issue:`29851`。)

importlib.find_spec() 如果指定的父模块不是包(即 缺少 __path__ 属性)。 (由 Milan Oberkirch 在 中提供:issue:`30436`。)

新的 importlib.source_hash() 可用于计算传递源的哈希值。 一个基于 哈希的 .pyc 文件 嵌入了此函数返回的值。


io

新的 TextIOWrapper.reconfigure() 方法可用于使用新设置重新配置文本流。 (由 Antoine Pitrou 在 :issue:`30526` 和 INADA Naoki 在 :issue:`15216` 中贡献。)


IP地址

ipaddress.IPv6Networkipaddress.IPv4Network 新的 subnet_of()supernet_of() 方法可用于网络遏制测试。 (由 Michel Albert 和 Cheryl Sabella 在 :issue:`20825` 中贡献。)


迭代工具

itertools.islice() 现在接受 类整数对象 作为开始、停止和切片参数。 (由 Will Roberts 在 :issue:`30537` 中贡献。)


语言环境

locale.format_string() 的新 monetary 参数可用于使转换使用货币千位分隔符和分组字符串。 (由 Garvit 在 中贡献:问题:`10379`。)

locale.getpreferredencoding() 函数现在在 Android 上或处于 强制 UTF-8 模式 时总是返回 'UTF-8'


日志记录

Logger 实例现在可以被腌制。 (由 Vinay Sajip 在 中提供:issue:`30520`。)

新的 StreamHandler.setStream() 方法可用于在处理程序创建后替换记录器流。 (由 Vinay Sajip 在 中提供:issue:`30522`。)

现在可以在传递给 logging.config.fileConfig() 的配置中为处理程序构造函数指定关键字参数。 (由 Preston Landers 在 中提供:issue:`31080`。)


数学

新的 math.remainder() 函数实现了 IEEE 754 风格的余数运算。 (由 Mark Dickinson 在 :issue:`29962` 中提供。)


模仿类型

.bmp 的 MIME 类型已从 'image/x-ms-bmp' 更改为 'image/bmp'。 (由 Nitish Chandra 在 中提供:issue:`22589`。)


msilib

新的 Database.Close() 方法可用于关闭 MSI 数据库。 (由 Berker Peksag 在 中提供:issue:`20486`。)


多处理

新的 Process.close() 方法显式关闭进程对象并释放与其关联的所有资源。 如果底层进程仍在运行,则会引发 ValueError。 (由 Antoine Pitrou 在 中提供:issue:`30596`。)

新的 Process.kill() 方法可用于在 Unix 上使用 SIGKILL 信号终止进程。 (由 Vitor Pereira 在 中提供:issue:`30794`。)

Process 创建的非守护线程现在在进程退出时加入。 (由 Antoine Pitrou 在 :issue:`18966` 中提供。)


操作系统

os.fwalk() 现在接受 path 参数作为 bytes。 (由 Serhiy Storchaka 在 中提供:issue:`28682`。)

os.scandir() 获得了对 文件描述符 的支持。 (由 Serhiy Storchaka 在 中提供:issue:`25996`。)

新的 register_at_fork() 函数允许注册 Python 回调以在进程 fork 处执行。 (由 Antoine Pitrou 在 中提供:issue:`16500`。)

添加了 os.preadv()(结合了 os.readv()os.pread())和 os.pwritev() 函数(结合 os.writev()os.pwrite() 的功能)。 (由 Pablo Galindo 在 中提供:issue:`31368`。)

os.makedirs() 的 mode 参数不再影响新创建的中级目录的文件权限位。 (由 Serhiy Storchaka 在 :issue:`19930` 中提供。)

os.dup2() 现在返回新的文件描述符。 以前,总是返回 None。 (由 Benjamin Peterson 在 中提供:issue:`32441`。)

os.stat() 返回的结构现在包含 st_fstype Solaris 及其派生的属性。 (由 Jesús Cea Avión 在 中提供:issue:`32659`。)


路径库

新的 Path.is_mount() 方法现在可用于 POSIX 系统,可用于确定路径是否为挂载点。 (由 Cooper Ry Lees 在 中提供:issue:`30897`。)


数据库

pdb.set_trace() 现在采用可选的 header 仅关键字参数。 如果给定,它会在调试开始之前打印到控制台。 (由 Barry Warsaw 在 中提供:issue:`31389`。)

pdb 命令行现在接受 -m module_name 作为脚本文件的替代。 (由 Mario Corchero 在 中提供:issue:`32206`。)


py_compile

py_compile.compile() – 通过扩展,compileall – 现在通过无条件创建 .pyc 来尊重 SOURCE_DATE_EPOCH 环境变量用于基于哈希验证的文件。 这允许在急切创建 .pyc 文件时保证 可重现的构建 。 (伯恩哈德 M 供稿) 中的 Wiedemann:问题:`29708`。)


pydoc

pydoc 服务器现在可以绑定到由新的 -n 命令行参数指定的任意主机名。 (由 Feanil Patel 在 中提供:issue:`31128`。)


队列

新的 SimpleQueue 类是一个无界的 FIFO 队列。 (由 Antoine Pitrou 在 中提供:issue:`14976`。)


关于

可以在组范围内设置标志 re.ASCIIre.LOCALEre.UNICODE。 (由 Serhiy Storchaka 在 中提供:issue:`31690`。)

re.split() 现在支持在匹配空字符串的模式上进行拆分,例如 r'\b''^$'(?=-)。 (由 Serhiy Storchaka 在 :issue:`25054` 中提供。)

使用 re.LOCALE 标志编译的正则表达式在编译时不再依赖于语言环境。 仅当使用编译的正则表达式时才应用区域设置。 (由 Serhiy Storchaka 在 中提供:issue:`30215`。)

FutureWarning 如果正则表达式包含将来会在语义上发生变化的字符集构造,例如嵌套集和集操作,现在会发出 。 (由 Serhiy Storchaka 在 中提供:issue:`30349`。)

现在可以使用 copy.copy()copy.deepcopy() 复制已编译的正则表达式和匹配对象。 (由 Serhiy Storchaka 在 :issue:`10076` 中提供。)


信号

signal.set_wakeup_fd() 函数的新 warn_on_full_buffer 参数可以指定 Python 在唤醒缓冲区溢出时是否在 stderr 上打印警告。 (由纳撒尼尔 J. 中的史密斯:问题:`30050`。)


插座

如果套接字处于阻塞模式,新的 socket.getblocking() 方法返回 True,否则返回 False。 (由 Yury Selivanov 在 中提供:issue:`32373`。)

新的 socket.close() 函数关闭传递的套接字文件描述符。 应使用此函数代替 os.close() 以获得更好的跨平台兼容性。 (由 Christian Heimes 在 中提供:issue:`32454`。)

socket 模块现在公开 socket.TCP_CONGESTION (Linux 2.6.13)、socket.TCP_USER_TIMEOUT (Linux 2.6.37) 和 socket.TCP_NOTSENT_LOWAT (Linux 3.12) 常量. (由 Omar Sandoval 在 :issue:`26273` 和 Nathaniel J. 中的史密斯:问题:`29728`。)

添加了对 socket.AF_VSOCK 套接字的支持,以允许虚拟机与其主机之间的通信。 (由 Cathy Avery 在 中提供:问题:`27584`。)

默认情况下,套接字现在从文件描述符中自动检测系列、类型和协议。 (由 Christian Heimes 在 中提供:issue:`28134`。)


套接字服务器

socketserver.ThreadingMixIn.server_close() 现在等待所有非守护线程完成。 socketserver.ForkingMixIn.server_close() 现在等待所有子进程完成。

socketserver.ForkingMixInsocketserver.ThreadingMixIn 类添加新的 socketserver.ForkingMixIn.block_on_close 类属性。 将类属性设置为 False 以获得 3.7 之前的行为。


sqlite3

sqlite3.Connection 现在在底层 SQLite 库为 3.6.11 或更高版本时公开 backup() 方法。 (由 Lele Gaifax 在 中提供:issue:`27645`。)

sqlite3.connect()database 参数现在接受任何 类似路径的对象 ,而不仅仅是一个字符串。 (由 Anders Lorentsen 在 中提供:issue:`31843`。)


ssl

ssl 模块现在使用 OpenSSL 的内置 API 而不是 match_hostname() 来检查主机名或 IP 地址。 在 TLS 握手期间验证值。 任何证书验证错误,包括主机名检查失败,现在都会引发 SSLCertVerificationError 并使用正确的 TLS 警报消息中止握手。 新的例外包含附加信息。 可以使用 SSLContext.hostname_checks_common_name 自定义主机名验证。 (由 Christian Heimes 在 中提供:issue:`31399`。)

笔记

改进的主机名检查需要与 OpenSSL 1.0.2 或 1.1 兼容的 libssl 实现。 因此,不再支持 OpenSSL 0.9.8 和 1.0.1(有关更多详细信息,请参阅 平台支持删除 )。 ssl 模块主要与 LibreSSL 2.7.2 及更新版本兼容。


ssl 模块不再在 SNI TLS 扩展中发送 IP 地址。 (由 Christian Heimes 在 中提供:issue:`32185`。)

match_hostname() 不再支持像 www*.example.org 这样的部分通配符。 (由 Mandeep Singh 在 :issue:`23033` 和 Christian Heimes 在 :issue:`31399` 中贡献。)

ssl 模块的默认密码套件选择现在使用黑名单方法而不是硬编码的白名单。 Python 不再重新启用已被 OpenSSL 安全更新阻止的密码。 可以在编译时配置默认密码套件选择。 (由 Christian Heimes 在 中提供:issue:`31429`。)

现在支持验证包含国际化域名 (IDN) 的服务器证书。 作为此更改的一部分,SSLSocket.server_hostname 属性现在以 A 标签形式("xn--pythn-mua.org")而不是 U 标签形式("pythön.org")存储预期的主机名)。 (由纳撒尼尔 J. 中的 Smith 和 Christian Heimes:问题:`28414`。)

ssl 模块对 TLS 1.3 和 OpenSSL 1.1.1 有初步和实验性的支持。 在 Python 3.7.0 发布时,OpenSSL 1.1.1 仍在开发中,TLS 1.3 尚未最终确定。 TLS 1.3 握手和协议的行为与 TLS 1.2 及更早版本略有不同,请参阅 TLS 1.3。 (由 Christian Heimes 在 :issue:`32947`:issue:`20995`:issue:`29136`:issue 中贡献:`30622`:问题:`33618`)

SSLSocketSSLObject 不再有公共构造函数。 直接实例化从来都不是记录在案和受支持的功能。 必须使用 SSLContext 方法 wrap_socket()wrap_bio() 创建实例。 (由 Christian Heimes 在 中提供:issue:`32951`

用于设置最小和最大 TLS 协议版本的 OpenSSL 1.1 API 可用作 SSLContext.minimum_versionSSLContext.maximum_version。 支持的协议由几个新标志指示,例如 HAS_TLSv1_1。 (由 Christian Heimes 在 中提供:issue:`32609`。)


细绳

string.Template 现在允许您有选择地分别修改花括号占位符和非花括号占位符的正则表达式模式。 (由 Barry Warsaw 在 中提供:issue:`1198569`。)


子流程

subprocess.run() 函数接受新的 capture_output 关键字参数。 当为 true 时,将捕获 stdout 和 stderr。 这相当于将 subprocess.PIPE 作为 stdoutstderr 参数传递。 (由 Bo Bayles 在 中提供:问题:`32102`。)

subprocess.run 函数和 subprocess.Popen 构造函数现在接受 text 关键字参数作为 universal_newlines 的别名。 (由 Andrew Clegg 在 中提供:问题:`31756`。)

在 Windows 上,重定向标准句柄时 close_fds 的默认值从 False 更改为 True。 现在可以在重定向标准句柄时将 close_fds 设置为 true。 参见 subprocess.Popen。 这意味着 close_fds 现在在所有支持的平台上默认为 True。 (由 Segev Finer 在 :issue:`19764` 中贡献。)

subprocess.call()subprocess.run()Popen 期间处理 KeyboardInterrupt 时,子进程模块现在更加优雅] 上下文管理器。 在继续处理 KeyboardInterrupt 异常之前,它现在等待子进程退出的一小段时间。 (由格雷戈里 P. 中的史密斯:问题:`25942`。)


系统

新的 sys.breakpointhook() 钩子函数由内置的 breakpoint() 调用。 (由 Barry Warsaw 在 中提供:issue:`31353`。)

在 Android 上,新的 sys.getandroidapilevel() 返回构建时 Android API 版本。 (由 Victor Stinner 在 中提供:问题:`28740`。)

新的 sys.get_coroutine_origin_tracking_depth() 函数返回当前协程原点跟踪深度,由新的 sys.set_coroutine_origin_tracking_depth() 设置。 asyncio 已转换为使用此新 API,而不是已弃用的 sys.set_coroutine_wrapper()。 (由纳撒尼尔 J. 中的史密斯:问题:`32591`。)


时间

PEP 564time 模块增加了六个具有纳秒级分辨率的新函数:

添加了新的时钟标识符:

新的 time.thread_time()time.thread_time_ns() 函数可用于获取每个线程的 CPU 时间测量。 (由 Antoine Pitrou 在 中提供:issue:`32025`。)

新的 time.pthread_getcpuclockid() 函数返回线程特定 CPU 时间时钟的时钟 ID。


特金特

新的 tkinter.ttk.Spinbox 类现已可用。 (由 Alan Moore 在 中提供:issue:`32585`。)


tracemalloc

tracemalloc.Traceback 的行为更像常规回溯,将帧从最旧到最新排序。 Traceback.format() 现在接受负 limit,将结果截断到 abs(limit) 最旧的帧。 要获得旧的行为,请使用新的 most_recent_first 参数到 Traceback.format()。 (由 Jesse Bakker 在 中提供:issue:`32121`。)


类型

新的 WrapperDescriptorTypeMethodWrapperTypeMethodDescriptorTypeClassMethodDescriptorType 类现在可用。 (由 Manuel Krebber 和 Guido van Rossum 在 :issue:`29377` 和 Serhiy Storchaka 在 :issue:`32265` 中贡献。)

新的 types.resolve_bases() 函数根据 PEP 560 的规定动态解析 MRO 条目。 (由 Ivan Levkivskyi 在 :issue:`32717` 中贡献。)


单码数据

内部 unicodedata 数据库已升级为使用 Unicode 11。 (本杰明·彼得森供稿。)


单元测试

新的 -k 命令行选项允许通过名称子字符串或类 Unix shell 模式过滤测试。 例如,python -m unittest -k foo 运行 foo_tests.SomeTest.test_somethingbar_tests.SomeTest.test_foo,但不运行 bar_tests.FooTest.test_something。 (由 Jonas Haag 在 中提供:issue:`32071`。)


单元测试.mock

哨兵 属性现在在 复制腌制 时保留其身份。 (由 Serhiy Storchaka 在 :issue:`20804` 中提供。)

新的 seal() 函数允许密封 Mock 实例,这将禁止进一步创建属性模拟。 密封被递归地应用于所有本身是模拟的属性。 (由 Mario Corchero 在 中提供:issue:`30541`。)


urllib.parse

urllib.parse.quote() 已从 RFC 2396 更新为 RFC 3986,添加 ~ 到默认情况下从不引用的字符集。 (由 Christian Theune 和 Ratnadeep Debnath 在 中提供:issue:`16285`。)


uu

uu.encode() 函数现在接受一个可选的 backtick 关键字参数。 当它为真时,零由 '`' 而不是空格表示。 (由 Zhang 在 中提供:issue:`30103`。)


用户名

新的 UUID.is_safe 属性从平台中继有关生成的 UUID 是否使用多处理安全方法生成的信息。 (由 Barry Warsaw 在 中提供:issue:`22807`。)

uuid.getnode() 现在比本地管理的 MAC 地址更喜欢通用管理的 MAC 地址。 这更好地保证了从 uuid.uuid1() 返回的 UUID 的全局唯一性。 如果只有本地管理的 MAC 地址可用,则返回找到的第一个此类地址。 (由 Barry Warsaw 在 中提供:issue:`32107`。)


警告

默认警告过滤器的初始化已更改如下:

  • 通过命令行选项启用的警告(包括 -b 和新的 CPython 特定的 -X dev 选项)总是通过 [ X186X]sys.warnoptions 属性。

  • 通过命令行或环境启用的警告过滤器现在具有以下优先顺序:

    • 用于 -b(或 -bb)的 BytesWarning 过滤器

    • 使用 -W 选项指定的任何过滤器

    • 使用 PYTHONWARNINGS 环境变量指定的任何过滤器

    • 任何其他 CPython 特定过滤器(例如 为新的 -X dev 模式添加的 default 过滤器)

    • 任何由警告机制直接定义的隐式过滤器


  • 在 CPython 调试版本中,现在默认显示所有警告(隐式过滤器列表为空)

(由 Nick Coghlan 和 Victor Stinner 在 :issue:`20361`:issue:`32043`:issue:`32230` 中贡献。)

默认情况下,弃用警告再次显示在单文件脚本和交互式提示中。 有关详细信息,请参阅 PEP 565:在 __main__ 中显示弃用警告。 (由 Nick Coghlan 在 :issue:`31975` 中提供。)


xml文件

find() 方法中的 ElementPath 谓词现在可以将当前节点的文本与 [. = "text"] 进行比较,而不仅仅是子节点中的文本。 谓词还允许添加空格以提高可读性。 (由 Stefan Behnel 在 中提供:issue:`31648`。)


xmlrpc.server

SimpleXMLRPCDispatcher.register_function 现在可以用作装饰器。 (由 Zhang 在 中提供:issue:`7769`。)


压缩包

函数 create_archive() 现在接受一个可选的 filter 参数,以允许用户选择应包含在存档中的文件。 (由 Irmen de Jong 在 中提供:issue:`31072`。)

函数 create_archive() 现在接受可选的 compressed 参数来生成压缩存档。 还添加了命令行选项 --compress 以支持压缩。 (由王志明在 中提供:issue:`31638`。)


压缩文件

ZipFile 现在接受新的 compresslevel 参数来控制压缩级别。 (由 Bo Bayles 在 中提供:issue:`21417`。)

ZipFile 创建的档案中的子目录现在按字母顺序存储。 (伯恩哈德 M 供稿) 中的 Wiedemann:问题:`30693`。)


C API 更改

已实现用于线程本地存储的新 API。 参见 PEP 539: New C API for Thread-Local Storage 的概述和 Thread Specific Storage (TSS) API 的完整参考。 (由 Masayuki Yamamoto 在 中贡献:issue:`25658`。)

新的 上下文变量 功能公开了许多 新的 C API

新的 PyImport_GetModule() 函数返回先前导入的具有给定名称的模块。 (由 Eric Snow 在 中提供:issue:`28411`。)

新的 Py_RETURN_RICHCOMPARE 宏简化了丰富的比较函数的编写。 (由 Petr Victorin 在 中提供:issue:`23699`。)

新的 Py_UNREACHABLE 宏可用于标记无法访问的代码路径。 (由 Barry Warsaw 在 中提供:issue:`31338`。)

tracemalloc 现在通过新的 PyTraceMalloc_Track()PyTraceMalloc_Untrack() 函数公开 C API。 (由 Victor Stinner 在 中提供:问题:`30054`。)

新的 import__find__load__start()import__find__load__done() 静态标记可用于跟踪模块导入。 (由 Christian Heimes 在 中提供:issue:`31574`。)

结构体 PyMemberDefPyGetSetDefPyStructSequence_Field、[X126X,Sequence1_X29X]的字段 namedoc wrapperbase 现在属于 const char * 类型,而不是 char *。 (由 Serhiy Storchaka 在 中提供:issue:`28761`。)

PyUnicode_AsUTF8AndSize()PyUnicode_AsUTF8() 的结果现在是 const char * 而不是 char * 类型。 (由 Serhiy Storchaka 在 中提供:issue:`28769`。)

PyMapping_Keys()PyMapping_Values()PyMapping_Items() 的结果现在总是一个列表,而不是一个列表或元组。 (由 Oren Milman 在 中提供:issue:`28280`。)

添加了函数 PySlice_Unpack()PySlice_AdjustIndices()。 (由 Serhiy Storchaka 在 中提供:issue:`27867`。)

PyOS_AfterFork() 被弃用,支持新函数 PyOS_BeforeFork(), PyOS_AfterFork_Parent() 和 PyOS_AfterFork_Child() (由 Antoine Pitrou 在 中提供:issue:`16500`。)

作为公共 API 一部分的 PyExc_RecursionErrorInst 单例已被删除,因为其成员从未被清除可能会在解释器的最终确定过程中导致段错误。 由 Xavier de Gaye 在 :issue:`22898`:issue:`30697` 中贡献。

使用时区构造函数 PyTimeZone_FromOffset()PyTimeZone_FromOffsetAndName() 添加了对时区的 C API 支持,并使用 PyDateTime_TimeZone_UTC 访问 UTC 单例。 由 Paul Ganssle 在 中贡献:issue:`10381`

PyThread_start_new_thread()PyThread_get_thread_ident()的结果类型,PyThreadState_SetAsyncExc()id参数从long变为[ X148X]无符号长。 (由 Serhiy Storchaka 在 中提供:issue:`6532`。)

PyUnicode_AsWideCharString() 如果第二个参数是 NULL 并且 wchar_t* 字符串包含空字符,现在会引发 ValueError。 (由 Serhiy Storchaka 在 中提供:issue:`30708`。)

对启动顺序和动态内存分配器管理的更改意味着在调用大多数 C API 函数之前调用 Py_Initialize() 的长期记录要求现在更加依赖,如果不遵守它可能会导致嵌入应用程序中的段错误。 有关更多详细信息,请参阅本文档中的 Porting to Python 3.7 部分和 C API 文档中的 Before Python Initialization 部分。

新的 PyInterpreterState_GetID() 返回给定解释器的唯一 ID。 (由 Eric Snow 在 中提供:问题:`29102`。)

Py_DecodeLocale()Py_EncodeLocale() 现在在启用 UTF-8 模式 时使用 UTF-8 编码。 (由 Victor Stinner 在 中提供:问题:`29240`。)

PyUnicode_DecodeLocaleAndSize()PyUnicode_EncodeLocale() 现在使用 surrogateescape 错误处理程序的当前语言环境编码。 (由 Victor Stinner 在 中提供:问题:`29240`。)

PyUnicode_FindChar()startend 参数现在被调整为像字符串切片一样。 (由 Zhang 在 中提供:issue:`28822`。)


构建更改

已删除对构建 --without-threads 的支持。 threading 模块现在始终可用。 (由 Antoine Pitrou 在 :issue:`31370` 中贡献。)。

在非 OSX UNIX 平台上构建 _ctypes 模块时,不再捆绑使用 libffi 的完整副本。 在此类平台上构建 _ctypes 时,现在需要安装 libffi 副本。 (由 Zachary Ware 在 中提供:issue:`27979`。)

Windows 构建过程不再依赖 Subversion 来拉入外部源,而是使用 Python 脚本从 GitHub 下载 zipfile。 如果在系统上找不到 Python 3.6(通过 py -3.6),NuGet 将用于下载 32 位 Python 的副本,用于此目的。 (由 Zachary Ware 在 中提供:issue:`30450`。)

ssl 模块需要与 OpenSSL 1.0.2 或 1.1 兼容的 libssl。 OpenSSL 1.0.1 已于 2016 年 12 月 31 日结束生命周期,不再受支持。 暂时也不支持 LibreSSL。 版本 2.6.4 之前的 LibreSSL 版本缺少所需的 OpenSSL 1.0.2 API。


优化

通过移植更多代码以使用 METH_FASTCALL 约定,调用在 C 中实现的各种标准库类的许多方法的开销已显着减少。 (由 Victor Stinner 在 :issue:`29300`:issue:`29507`:issue:`29452`中贡献:问题:`29286`。)

各种优化将 Python 启动时间减少了 10% on Linux,最多 30% on macOS。 (由 Victor Stinner、INADA Naoki 在 :issue:`29585` 和 Ivan Levkivskyi 在 :issue:`31333` 中贡献。)

由于避免创建绑定方法实例的字节码更改,方法调用现在高达 20% faster。 (由 Yury Selivanov 和 INADA Naoki 在 中提供:issue:`26110`。)

asyncio 模块对常用函数进行了许多显着优化:

由于 PEP 560 worktyping 的导入时间减少了 7 倍,许多打字操作现在更快了。 (由 Ivan Levkivskyi 在 :issue:`32226` 中贡献。)

sorted()list.sort() 已针对常见情况进行了优化,最高可达 40-75% faster。 (由 Elliot Gorokhovsky 在 :issue:`28685` 中贡献。)

dict.copy() 现在最多快 5.5 倍。 (由 Yury Selivanov 在 中提供:issue:`31179`。)

hasattr()getattr() 现在在 name 未找到且 obj 不覆盖 时快约 4 倍object.__getattr__()object.__getattribute__()。 (由稻田直树在 中提供:issue:`32544`。)

在字符串中搜索某些 Unicode 字符(如乌克兰大写“Є”)比搜索其他字符慢 25 倍。 在最坏的情况下,它现在只慢了 3 倍。 (由 Serhiy Storchaka 在 中提供:issue:`24821`。)

重新实现了 collections.namedtuple() 工厂,使命名元组的创建速度提高了 4 到 6 倍。 (由 Jelle Zijlstra 提供,并由 INADA Naoki、Serhiy Storchaka 和 Raymond Hettinger 在 :issue:`28638` 中进一步改进。)

date.fromordinal()date.fromtimestamp() 现在在普通情况下高达 30% faster。 (由 Paul Ganssle 在 :issue:`32403` 中提供。)

由于使用了 os.scandir()os.fwalk() 函数现在最多快 2 倍。 (由 Serhiy Storchaka 在 中提供:issue:`25996`。)

由于使用了 os.scandir() 函数,shutil.rmtree() 函数的速度提高了 20-40%。 (由 Serhiy Storchaka 在 中提供:issue:`28564`。)

优化 正则表达式 的不区分大小写匹配和搜索。 搜索某些模式现在可以快 20 倍。 (由 Serhiy Storchaka 在 中提供:issue:`30285`。)

re.compile() 现在将 flags 参数转换为 int 对象,如果它是 RegexFlag。 它现在和 Python 3.5 一样快,比 Python 3.6 快大约 10% d 取决于模式。 (由稻田直树在 中提供:issue:`31671`。)

selectors.EpollSelectorselectors.PollSelectorselectors.DevpollSelectormodify() 方法可能在 10% f 左右在重负载下。 (由 Giampaolo Rodola 在 中提供:issue:`30014`

常量折叠已从窥孔优化器移动到新的 AST 优化器,它能够更一致地执行优化。 (由 Eugene Toder 和 INADA Naoki 在 :issue:`29469`:issue:`11549` 中贡献。)

abc 中的大多数函数和方法都已用 C 重写。 这使得抽象基类的创建和调用 isinstance()issubclass() 的速度提高了 1.5 倍。 这也将 Python 启动时间减少了 10%。 (由 Ivan Levkivskyi 和 INADA Naoki 在 中提供:issue:`31333`

通过在不构造子类时使用快速路径构造函数,显着提高了 datetime.datedatetime.datetime 的替代构造函数的速度。 (由 Paul Ganssle 在 中提供:issue:`32403`

array.array 实例的比较速度在某些情况下得到了显着提高。 比较保存相同整数类型值的数组时,现在速度提高了 10 倍到 70 倍。 (由 Adrian Wielgosik 在 :issue:`24700` 中贡献。)

math.erf()math.erfc() 函数现在在大多数平台上使用(更快)C 库实现。 (由 Serhiy Storchaka 在 中提供:issue:`26121`。)


其他 CPython 实现更改

  • 跟踪钩子现在可以选择不接收 line 并选择接收来自解释器的 opcode 事件,方法是在被追踪的帧。 (由 Nick Coghlan 在 中提供:issue:`31344`。)
  • 修复了命名空间包模块属性的一些一致性问题。 命名空间模块对象现在有一个 __file__ 设置为 None(以前未设置),并且它们的 __spec__.origin 也设置为 None(以前的字符串 [ X160X])。 参见 :issue:`32305`。 此外,命名空间模块对象的 __spec__.loader 设置为与 __loader__ 相同的值(以前,前者设置为 None)。 参见 :issue:`32303`
  • locals() 字典现在按变量定义的词法顺序显示。 以前,订单是未定义的。 (由 Raymond Hettinger 在 中提供:issue:`32690`。)
  • distutils upload 命令不再尝试将 CR 行尾字符更改为 CRLF。 这修复了以相当于 CR 的字节结尾的 sdists 损坏问题。 (由 Bo Bayles 在 中提供:问题:`32304`。)


弃用的 Python 行为

Yield 表达式(yieldyield from 子句)现在在推导式和生成器表达式中被弃用(除了最左边的 for 子句中的可迭代表达式)。 这确保推导式总是立即返回适当类型的容器(而不是潜在地返回 generator iterator 对象),而生成器表达式不会尝试将其隐式输出与任何显式 yield 表达式的输出交错. 在 Python 3.7 中,此类表达式在编译时发出 DeprecationWarning,在 Python 3.8 中,这将是 SyntaxError。 (由 Serhiy Storchaka 在 :issue:`10544` 中提供。)

object.__complex__() 返回 complex 的子类已被弃用,并且在未来的 Python 版本中会出错。 这使得 __complex__()object.__int__()object.__float__() 一致。 (由 Serhiy Storchaka 在 中提供:issue:`28894`。)


弃用的 Python 模块、函数和方法

国际金融中心

aifc.openfp() 已弃用,将在 Python 3.9 中删除。 改用 aifc.open()。 (由 Brian Curtin 在 中贡献:问题:`31985`。)


异步

asyncio.Lock 和其他异步同步原语的直接 await-ing 实例的支持已被弃用。 必须使用异步上下文管理器来获取和释放同步资源。 (由 Andrew Svetlov 在 中提供:issue:`32253`。)

asyncio.Task.current_task()asyncio.Task.all_tasks() 方法已被弃用。 (由 Andrew Svetlov 在 中提供:issue:`32250`。)


收藏

在 Python 3.8 中,collections.abc 中的抽象基类将不再在常规 collections 模块中公开。 这将有助于在具体类和抽象基类之间创建更清晰的区别。 (由 Serhiy Storchaka 在 中提供:issue:`25988`。)


数据库

dbm.dumb 现在支持读取只读文件,不再写入未更改的索引文件。 如果索引文件丢失并在 'r''w' 模式下重新创建,则会发出弃用警告(这将是未来 Python 版本中的错误)。 (由 Serhiy Storchaka 在 中提供:issue:`28847`。)


枚举

在 Python 3.8 中,尝试检查 Enum 类中的非 Enum 对象将引发 TypeError(例如 1 in Color); 类似地,尝试检查 Flag 成员中的非标志对象将引发 TypeError(例如 1 in Perm.RW); 目前,这两个操作都返回 False。 (由 Ethan Furman 在 中提供:issue:`33217`。)


获取文本

现在不推荐使用非整数值在 gettext 中选择复数形式。 它从来没有正确工作。 (由 Serhiy Storchaka 在 中提供:issue:`28692`。)


导入库

方法 MetaPathFinder.find_module()(替换为 MetaPathFinder.find_spec())和 PathEntryFinder.find_loader()(替换为 PathEntryFinder.find_spec ) 在 Python 3.4 中都已弃用,现在发出 DeprecationWarning。 (由 Matthias Bussonnier 在 中提供:issue:`29576`

importlib.abc.ResourceLoader ABC 已被弃用,取而代之的是 importlib.abc.ResourceReader


语言环境

locale.format() 已被弃用,请改用 locale.format_string()。 (由 Garvit 在 中贡献:问题:`10379`。)


路径

macpath 现在已弃用,将在 Python 3.8 中删除。 (由 Chi Hsuan Yen 在 中提供:issue:`9850`。)


穿线

dummy_threading_dummy_thread 已被弃用。 不再可能在禁用线程的情况下构建 Python。 改用 线程 。 (由 Antoine Pitrou 在 中提供:issue:`31370`。)


插座

socket.htons()socket.ntohs() 中的静默参数值截断已被弃用。 在 Python 的未来版本中,如果传递的参数大于 16 位,则会引发异常。 (由 Oren Milman 在 中提供:issue:`28332`。)


ssl

ssl.wrap_socket() 已弃用。 改用 ssl.SSLContext.wrap_socket()。 (由 Christian Heimes 在 中提供:问题:`28124`。)


苏瑙

sunau.openfp() 已弃用,将在 Python 3.9 中删除。 改用 sunau.open()。 (由 Brian Curtin 在 中贡献:问题:`31985`。)


系统

已弃用 sys.set_coroutine_wrapper()sys.get_coroutine_wrapper()

未记录的 sys.callstats() 函数已被弃用,并将在未来的 Python 版本中删除。 (由 Victor Stinner 在 中提供:问题:`28799`。)


海浪

wave.openfp() 已弃用,将在 Python 3.9 中删除。 改用 wave.open()。 (由 Brian Curtin 在 中贡献:问题:`31985`。)


不推荐使用的 C API 函数和类型

如果 Py_LIMITED_API 未设置或设置为 0x030504000x03060000 之间范围内的值,则函数 PySlice_GetIndicesEx() 已弃用并替换为宏(不包括在内),或者是 0x03060100 或更高。 (由 Serhiy Storchaka 在 中提供:issue:`27867`。)

PyOS_AfterFork() 已被弃用。 改用 PyOS_BeforeFork()PyOS_AfterFork_Parent()PyOS_AfterFork_Child()。 (由 Antoine Pitrou 在 中提供:issue:`16500`。)


平台支撑拆除

  • 不再正式支持 FreeBSD 9 及更早版本。

  • 对于完整的 Unicode 支持,包括在扩展模块中,*nix 平台现在预计至少提供 C.UTF-8(完整区域设置)、C.utf8(完整区域设置)或 UTF-8 之一(LC_CTYPE-only 语言环境)作为旧的基于 ASCIIC 语言环境的替代。

  • 不再支持 OpenSSL 0.9.8 和 1.0.1,这意味着在仍然使用这些版本的旧平台上构建具有 SSL/TLS 支持的 CPython 3.7 需要链接到更新版本的 OpenSSL 的自定义构建选项。

    值得注意的是,此问题会影响 Debian 8(又名“jessie”)和 Ubuntu 14.04(又名“Trusty”)LTS Linux 发行版,因为它们默认仍使用 OpenSSL 1.0.1。

    Debian 9(“stretch”)和 Ubuntu 16.04(“xenial”),以及其他 LTS Linux 版本的最新版本(例如 RHEL/CentOS 7.5、SLES 12-SP3),使用 OpenSSL 1.0.2 或更高版本,并在默认构建配置中保持受支持。

    CPython 自己的 :source:`CI 配置文件 <.travis.yml>` 提供了使用 SSL 的示例 :source:`兼容性测试基础设施 ` 在 CPython 的测试套件中构建和链接 OpenSSL 1.1.0 而不是提供 OpenSSL 的过时系统。


API 和功能删除

以下功能和 API 已从 Python 3.7 中删除:

  • os.stat_float_times() 功能已被移除。 它是在 Python 2.3 中引入的,用于向后兼容 Python 2.2,但自 Python 3.1 起已弃用。
  • '\'re.sub() 的替换模板中的 ASCII 字母组成的未知转义在 Python 3.5 中已被弃用,现在将导致错误。
  • 删除了对 tarfile.TarFile.add() 中的 exclude 参数的支持。 它在 Python 2.7 和 3.2 中被弃用。 请改用 filter 参数。
  • ntpath 模块中的 splitunc() 函数在 Python 3.1 中已被弃用,现在已被删除。 请改用 splitdrive() 函数。
  • collections.namedtuple() 不再支持 verbose 参数或 _source 属性,它显示了命名元组类的生成源代码。 这是旨在加速类创建的优化的一部分。 (由 Jelle Zijlstra 提供,并由 INADA Naoki、Serhiy Storchaka 和 Raymond Hettinger 在 :issue:`28638` 中进一步改进。)
  • 函数 bool()float()list()tuple() 不再接受关键字参数。 int() 的第一个参数现在只能作为位置参数传递。
  • 删除了以前在 plistlib 模块中的 Python 2.4 类 PlistDict_InternalDict 中弃用。 函数 readPlist()readPlistFromBytes() 的结果中的字典值现在是正常的字典。 您不再可以使用属性访问来访问这些词典的项目。
  • asyncio.windows_utils.socketpair() 功能已被移除。 改用 socket.socketpair() 函数,它在 Python 3.5 之后的所有平台上都可用。 asyncio.windows_utils.socketpair 只是 Python 3.5 及更新版本中 socket.socketpair 的别名。
  • asyncio 不再将 selectors_overlapped 模块导出为 asyncio.selectorsasyncio._overlapped。 将 from asyncio import selectors 替换为 import selectors
  • 现在禁止直接实例化 ssl.SSLSocketssl.SSLObject 对象。 构造函数从未被记录、测试或设计为公共构造函数。 用户应该使用 ssl.wrap_socket()ssl.SSLContext。 (由 Christian Heimes 在 中提供:issue:`32951`。)
  • 未使用的 distutils install_misc 命令已被删除。 (由埃里克 N。 中的 Vander Weele:问题:`29218`。)


模块拆卸

fpectl 模块已被移除。 默认情况下它从未启用,从未在 x86-64 上正常工作,并且它以导致 C 扩展意外损坏的方式更改了 Python ABI。 (由纳撒尼尔 J. 中的史密斯:问题:`29137`。)


仅限 Windows 的更改

python 启动器 (py.exe) 可以接受 32 位和 64 位说明符没有还必须指定一个次要版本。 所以 py -3-32py -3-64py -3.7-32 一样有效,还有 -m-64 和 -mn-64 形式现在接受强制使用 64 位 python,即使否则会使用 32 位。 如果指定的版本不可用 py.exe 将错误退出。 (由 Steve Barnes 在 :issue:`30291` 中提供。)

启动器可以作为 py -0 运行以生成已安装 python 的列表, 默认标有星号 。 运行 py -0p 将包含路径。 如果 py 使用无法匹配的版本说明符运行,它还会打印可用说明符的 短格式 列表。 (由 Steve Barnes 在 :issue:`30362` 中提供。)


移植到 Python 3.7

本节列出了可能需要更改您的代码的先前描述的更改和其他错误修正。

Python 行为的变化

  • asyncawait 名称现在是保留关键字。 使用这些名称作为标识符的代码现在将引发 SyntaxError。 (由 Jelle Zijlstra 在 中提供:issue:`30406`。)

  • PEP 479 为 Python 3.7 中的所有代码启用,这意味着 StopIteration 在协程和生成器中直接或间接引发的异常被转换为 RuntimeError ] 例外。 (由 Yury Selivanov 在 :issue:`32670` 中贡献。)

  • object.__aiter__() 方法不能再被声明为异步的。 (由 Yury Selivanov 在 中提供:issue:`31709`。)

  • 由于疏忽,早期的 Python 版本错误地接受了以下语法:

    f(1 for x in [1],)
    
    class C(1 for x in [1]):
        pass

    Python 3.7 现在正确地引发 SyntaxError,因为生成器表达式总是需要直接在一组括号内,并且两边不能有逗号,并且括号的重复只能在调用时省略。 (由 Serhiy Storchaka 在 :issue:`32012`:issue:`32023` 中贡献。)

  • 使用 -m 开关时,初始工作目录现在添加到 sys.path,而不是空字符串(在每次导入时动态表示当前工作目录) )。 任何检查空字符串或依赖先前行为的程序都需要相应地更新(例如 通过还检查 os.getcwd()os.path.dirname(__main__.__file__),具体取决于代码首先检查空字符串的原因)。


Python API 的变化


C API 的变化

函数 PySlice_GetIndicesEx() 对于可调整大小的序列被认为是不安全的。 如果切片索引不是 int 的实例,而是实现 __index__() 方法的对象,则可以在将其长度传递给 !PySlice_GetIndicesEx 后调整序列的大小。 这可能导致返回超出序列长度的索引。 为了避免可能出现的问题,请使用新函数 PySlice_Unpack()PySlice_AdjustIndices()。 (由 Serhiy Storchaka 在 中提供:issue:`27867`。)


CPython 字节码更改

有两个新的操作码::opcode:`LOAD_METHOD`:opcode:`CALL_METHOD`。 (由 Yury Selivanov 和 INADA Naoki 在 中提供:issue:`26110`。)

:opcode:`STORE_ANNOTATION` 操作码已被删除。 (由 Mark Shannon 在 :issue:`32550` 中贡献。)


仅限 Windows 的更改

用于覆盖 sys.path 的文件现在称为 <python-executable>._pth 而不是 'sys.path'。 有关详细信息,请参阅 查找模块 。 (由 Steve Dower 在 中提供:issue:`28137`。)


其他 CPython 实现更改

为了准备未来对公共 CPython 运行时初始化 API 的潜在更改(请参阅 PEP 432 的初始草案,但有些过时),CPython 的内部启动和配置管理逻辑已经显着重构。 虽然这些更新旨在对嵌入应用程序和常规 CPython CLI 的用户完全透明,但在此提到它们是因为重构在解释器启动期间改变了各种操作的内部顺序,因此可能会发现以前的潜在缺陷,或者在嵌入应用程序中,或在 CPython 本身中。 (最初由 Nick Coghlan 和 Eric Snow 作为 :issue:`22257` 的一部分贡献,并由 Nick、Eric 和 Victor Stinner 在许多其他问题中进一步更新)。 一些已知细节受到影响:

由于默认警告过滤器的配置方式发生了变化,将 Py_BytesWarningFlag 设置为大于 1 的值不再足以发出 BytesWarning 消息并将它们转换为异常。 相反,必须设置标志(以首先发出警告),并添加显式 error::BytesWarning 警告过滤器以将它们转换为异常。

由于编译器处理文档字符串的方式发生了变化,仅由文档字符串组成的函数体中的隐式 return None 现在被标记为与文档字符串在同一行上,而不是在函数的标题行上.

当前异常状态已从框架对象移动到协程。 这简化了解释器并修复了一些由进入或退出生成器时交换异常状态引起的模糊错误。 (由 Mark Shannon 在 :issue:`25612` 中贡献。)


Python 3.7.1 中的显着变化

从 3.7.1 开始,Py_Initialize() 现在一致地读取和尊重所有与 Py_Main() 相同的环境设置(在早期的 Python 版本中,它尊重定义不明确的子集这些环境变量,而在 Python 3.7.0 中,由于 :issue:`34247`,它没有读取其中任何一个。 如果不需要这种行为,请在调用 Py_Initialize() 之前将 Py_IgnoreEnvironmentFlag 设置为 1。

在 3.7.1 中,上下文变量 的 C API 已更新 以使用 PyObject 指针。 另见 :issue:`34762`

在 3.7.1 中,tokenize 模块现在在提供没有尾随换行符的输入时隐式发出 NEWLINE 标记。 此行为现在与 C 标记器在内部执行的操作相匹配。 (由 Ammar Askar 在 中提供:issue:`33899`。)


Python 3.7.2 中的显着变化

在 3.7.2 中,Windows 上的 venv 不再复制原始二进制文件,而是创建名为 python.exepythonw.exe 的重定向程序脚本。 这解决了一个长期存在的问题,即每次 Python 更新都必须升级或重新创建所有虚拟环境。 但是,请注意,此版本仍需要重新创建虚拟环境才能获得新脚本。


Python 3.7.6 中的显着变化

由于重大的安全问题,不再支持 asyncio.loop.create_datagram_endpoint()reuse_address 参数。 这是因为 UDP 中套接字选项 SO_REUSEADDR 的行为。 有关更多详细信息,请参阅 loop.create_datagram_endpoint() 的文档。 (由 Kyle Stanley、Antoine Pitrou 和 Yury Selivanov 在 :issue:`37228` 中提供。)


Python 3.7.10 中的显着变化

早期的 Python 版本允许使用 ;& 作为 urllib.parse.parse_qs()urllib.parse.parse_qsl() 中的查询参数分隔符]。 出于安全考虑,并符合更新的 W3C 建议,这已更改为仅允许单个分隔符键,默认值为 &。 此更改也会影响 cgi.parse()cgi.parse_multipart(),因为它们在内部使用受影响的函数。 有关更多详细信息,请参阅它们各自的文档。 (由 Adam Goldschmidt、Senthil Kumaran 和 Ken Jin 在 :issue:`42967` 中贡献。)