Python 3.7 的新特性 — Python 文档
Python 3.7 中的新功能
- 编辑
- 埃尔维斯·普兰斯克维奇 < 猫王@magic.io >
本文解释了 Python 3.7 中与 3.6 相比的新特性。 Python 3.7 于 2018 年 6 月 27 日发布。 有关完整详细信息,请参阅 变更日志 。
摘要 – 发布亮点
新的语法特性:
- PEP 563,推迟了对类型注释的评估。
向后不兼容的语法更改:
新的库模块:
新的内置功能:
- PEP 553,新的 breakpoint() 函数。
Python 数据模型改进:
- PEP 562,自定义访问模块属性。
- PEP 560,对输入模块和泛型类型的核心支持。
- dict 对象 的插入顺序保留特性已声明 是 Python 语言规范的官方部分。
标准库的重大改进:
CPython 实现改进:
- 避免使用 ASCII 作为默认文本编码:
- PEP 552,确定性 .pycs
- 新的 Python 开发模式
- PEP 565,改进的 DeprecationWarning 处理
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 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 的语言环境。
作为此更改的一部分,stdin 和 stdout 的默认错误处理程序在使用任何已定义的强制目标语言环境(当前为 C.UTF-8
、C.utf8
和 UTF-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 540:强制 UTF-8 运行时模式
新的 -X utf8
命令行选项和 PYTHONUTF8 环境变量可用于启用 CPython UTF-8 模式[ X152X]。
在 UTF-8 模式下,CPython 会忽略区域设置,并默认使用 UTF-8 编码。 sys.stdin 和 sys.stdout 流的错误处理程序设置为 surrogateescape
。
强制 UTF-8 模式可用于更改嵌入式 Python 解释器中的文本处理行为,而无需更改嵌入应用程序的区域设置。
尽管 PEP 540 的 UTF-8 模式的优点是无论运行系统上有哪些区域设置都可以工作,但它的缺点是对扩展模块(例如作为 GNU readline
)、运行非 Python 应用程序的子进程和运行旧版本 Python 的子进程。 为了降低与此类组件通信时损坏文本数据的风险,Python 3.7 还实现了 PEP 540:强制 UTF-8 运行时模式 )。
当语言环境为 C
或 POSIX
时默认启用 UTF-8 模式,并且 PEP 538 语言环境强制功能无法更改它到基于 UTF-8 的替代方案(无论失败是由于设置了 PYTHONCOERCECLOCALE=0
、设置了 LC_ALL
,还是缺少合适的目标语言环境)。
PEP 553:内置 breakpoint()
Python 3.7 包含新的内置 breakpoint() 函数,作为进入 Python 调试器的一种简单且一致的方式。
内置 breakpoint()
调用 sys.breakpointhook()。 默认情况下,后者导入pdb,然后调用pdb.set_trace()
,但是通过将sys.breakpointhook()
绑定到您选择的函数,breakpoint()
可以进入任何调试器。 此外,环境变量 PYTHONBREAKPOINT 可以设置为您选择的调试器的可调用对象。 设置PYTHONBREAKPOINT=0
完全禁用内置breakpoint()
。
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 562:自定义访问模块属性
Python 3.7 允许在模块上定义 __getattr__()
,并在找不到模块属性时调用它。 现在也允许在模块上定义 __dir__()
。
这可能有用的一个典型例子是模块属性弃用和延迟加载。
PEP 564:具有纳秒分辨率的新时间函数
现代系统中时钟的分辨率可能超过 time.time() 函数及其变体返回的浮点数的有限精度。 为避免精度损失,PEP 564 向 time 模块添加了现有计时器函数的六个新的“纳秒”变体:
time.clock_gettime_ns()
time.clock_settime_ns()
time.monotonic_ns()
time.perf_counter_ns()
time.process_time_ns()
time.time_ns()
新函数将纳秒数作为整数值返回。
Measurements 表明,在 Linux 和 Windows 上,time.time_ns() 的分辨率大约比 time.time() 的分辨率好 3 倍。
PEP 565:在 __main__ 中显示弃用警告
DeprecationWarning 的默认处理已更改,这些警告在默认情况下再次显示,但仅当触发它们的代码直接在 __main__ 模块中运行时。 因此,单文件脚本的开发人员和交互式使用 Python 的开发人员应该再次开始看到他们使用的 API 的弃用警告,但默认情况下,由导入的应用程序、库和框架模块触发的弃用警告将继续隐藏。
由于此更改,标准库现在允许开发人员在三种不同的弃用警告行为之间进行选择:
- FutureWarning:默认情况下始终显示,推荐用于应用程序最终用户看到的警告(例如 对于已弃用的应用程序配置设置)。
- DeprecationWarning:默认情况下仅显示在 __main__ 和运行测试时,推荐用于其他 Python 开发人员看到的警告,其中版本升级可能导致行为改变或错误。
- PendingDeprecationWarning:仅在运行测试时默认显示,用于未来版本升级将警告类别更改为 DeprecationWarning 或 FutureWarning 的情况。
以前,DeprecationWarning 和 PendingDeprecationWarning 仅在运行测试时可见,这意味着主要编写单文件脚本或交互式使用 Python 的开发人员可能会对他们使用的 API 中的重大更改感到惊讶。
PEP 560:对 typing 模块和泛型类型的核心支持
最初 PEP 484 的设计方式是不会对核心 CPython 解释器引入 任何 更改。 现在输入提示和 typing 模块被社区广泛使用,所以这个限制被删除了。 PEP 引入了两个特殊方法 __class_getitem__()
和 __mro_entries__
,这些方法现在被 typing 中的大多数类和特殊构造使用。 因此,类型的各种操作的速度提高了 7 倍,可以使用泛型类型而不会发生元类冲突,并且修复了 typing 模块中的几个长期存在的错误。
PEP 552:基于哈希的 .pyc 文件
Python 传统上通过比较源元数据(最后修改的时间戳和大小)与缓存文件头中保存的源元数据来检查字节码缓存文件(即 .pyc
文件)的最新性。生成。 虽然有效,但这种失效方法有其缺点。 当文件系统时间戳太粗糙时,Python 可能会错过源更新,导致用户混淆。 此外,缓存文件中的时间戳对于 构建重现性 和基于内容的构建系统来说是有问题的。
PEP 552 扩展了 pyc 格式,允许使用源文件的哈希值而不是源时间戳来进行失效。 这样的 .pyc
文件被称为“基于哈希的”。 默认情况下,Python 仍然使用基于时间戳的失效,并且不会在运行时生成基于哈希的 .pyc
文件。 可以使用 py_compile 或 compileall 生成基于哈希的 .pyc
文件。
基于哈希的 .pyc
文件有两种变体:已选中和未选中。 Python 在运行时根据相应的源文件验证已检查的基于哈希的 .pyc
文件,但不会对未检查的基于哈希的 pyc 进行验证。 未经检查的基于散列的 .pyc
文件对于 Python 外部系统(例如构建系统)负责使 .pyc
文件保持最新的环境是一种有用的性能优化。
有关更多信息,请参阅 缓存字节码失效 。
Python 开发模式 (-X dev)
新的 -X dev
命令行选项或新的 PYTHONDEVMODE 环境变量可用于启用 Python 开发模式 ]。 在开发模式下,Python 会执行额外的运行时检查,这些检查的成本太高而无法默认启用。 有关完整说明,请参阅 Python 开发模式 文档。
其他语言更改
- 由于实现问题,await 表达式和包含 async for 子句的推导在 格式化字符串文字 中的表达式中是非法的。 在 Python 3.7 中,这个限制被取消了。
- 现在可以将 255 个以上的参数传递给一个函数,一个函数现在可以有 255 个以上的参数。 (由 Serhiy Storchaka 在 :issue:`12844` 和 :issue:`18896` 中贡献。)
- bytes.fromhex() 和 bytearray.fromhex() 现在忽略所有 ASCII 空格,而不仅仅是空格。 (由 Robert Xiao 在 中提供:issue:`28927`。)
- str、bytes 和 bytearray 获得了对新的 isascii() 方法的支持,该方法可用于测试字符串或字节仅包含 ASCII 字符。 (由稻田直树在 中提供:issue:`32677`。)
- ImportError 现在在
from ... import ...
失败时显示模块名称和模块__file__
路径。 (由 Matthias Bussonnier 在 :issue:`29546` 中提供。) - 现在支持涉及将子模块绑定到名称的绝对导入的循环导入。 (由 Serhiy Storchaka 在 :issue:`30024` 中提供。)
object.__format__(x, )
现在等同于str(x)
而不是format(str(self),
)
。 (由 Serhiy Storchaka 在 中提供:issue:`28974`。)- 为了更好地支持动态创建堆栈跟踪,现在可以从 Python 代码实例化 types.TracebackType,并且 tracebacks 上的
tb_next
属性现在是可写的。 (由纳撒尼尔 J. 中的史密斯:问题:`30579`。) - 使用 -m 开关时,
sys.path[0]
现在会急切地扩展到完整的起始目录路径,而不是保留为空目录(允许从 current 导入] 导入时的工作目录)(由 Nick Coghlan 在 :issue:`33053` 中贡献。) - 新的 -X
importtime
选项或 PYTHONPROFILEIMPORTTIME 环境变量可用于显示每个模块导入的时间。 (由 Victor Stinner 在 中提供:问题:`31415`。)
新模块
上下文变量
新的 contextvars 模块和一组 新的 C API 引入了对 上下文变量 的支持。 上下文变量在概念上类似于线程局部变量。 与 TLS 不同,上下文变量正确支持异步代码。
asyncio 和 decimal 模块已更新为使用和支持开箱即用的上下文变量。 特别是活动的十进制上下文现在存储在上下文变量中,它允许十进制操作与异步代码中的正确上下文一起工作。
数据类
新的 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)"
导入lib.resources
新的 importlib.resources 模块提供了几个新的 API 和一个新的 ABC,用于访问、打开和读取包内的 resources。 资源大致类似于包内的文件,但它们不必是物理文件系统上的实际文件。 模块加载器可以提供一个 get_resource_reader()
函数,它返回一个 importlib.abc.ResourceReader 实例来支持这个新的 API。 内置文件路径加载器和 zip 文件加载器都支持这一点。
由 Barry Warsaw 和 Brett Cannon 在 中贡献:issue:`32248`。
改进的模块
异步
asyncio 模块获得了许多新功能、可用性和 性能改进 。 显着的变化包括:
新的 provisional asyncio.run() 函数可用于通过自动创建和销毁事件循环从同步代码运行协程。 (由 Yury Selivanov 在 :issue:`32314` 中贡献。)
asyncio 获得了对 contextvars 的支持。 loop.call_soon()、loop.call_soon_threadsafe()、loop.call_later()、loop.call_at()和[ X122X]Future.add_done_callback() 有一个新的可选关键字-only context 参数。 任务现在自动跟踪它们的上下文。 有关更多详细信息,请参阅 PEP 567。 (由 Yury Selivanov 在 :issue:`32436` 中贡献。)
新的 asyncio.create_task() 函数已添加为
asyncio.get_event_loop().create_task()
的快捷方式。 (由 Andrew Svetlov 在 中提供:issue:`32311`。)新的
loop.start_tls()
方法可用于将现有连接升级到 TLS。 (由 Yury Selivanov 在 中提供:issue:`23749`。)新的
loop.sock_recv_into()
方法允许将数据从套接字直接读取到提供的缓冲区中,从而可以减少数据副本。 (由 Antoine Pitrou 在 中提供:issue:`31819`。)新的 asyncio.current_task() 函数返回当前运行的 Task 实例,新的 asyncio.all_tasks() 函数返回一组所有现有的
Task
给定循环中的实例。Task.current_task()
和Task.all_tasks()
方法已被弃用。 (由 Andrew Svetlov 在 中提供:issue:`32250`。)新的 provisional BufferedProtocol 类允许通过手动控制接收缓冲区来实现流协议。 (由 Yury Selivanov 在 :issue:`32251` 中贡献。)
新的 asyncio.get_running_loop() 函数返回当前正在运行的循环,如果没有循环正在运行,则会引发 RuntimeError。 这与 asyncio.get_event_loop() 形成对比,如果没有运行,它将 创建 一个新的事件循环。 (由 Yury Selivanov 在 :issue:`32269` 中贡献。)
新的
StreamWriter.wait_closed()
协程方法允许等待流写入器关闭。 新的 StreamWriter.is_closure() 方法可用于确定编写器是否正在关闭。 (由 Andrew Svetlov 在 :issue:`32391` 中提供。)新的
loop.sock_sendfile()
协程方法允许在可能的情况下使用 os.sendfile 发送文件。 (由 Andrew Svetlov 在 中提供:issue:`32410`。)新的 Future.get_loop() 和
Task.get_loop()
方法返回创建任务或未来的循环实例。 Server.get_loop() 允许对 asyncio.Server 对象执行相同的操作。 (由 Yury Selivanov 在 :issue:`32415` 和 Srinivas Reddy Thatiparthy 在 :issue:`32418` 中贡献。)现在可以控制 asyncio.Server 的实例如何开始服务。 以前,服务器会在创建后立即开始提供服务。 新的 start_serving 关键字参数
loop.create_server()
和loop.create_unix_server()
,以及Server.start_serving()
和Server.serve_forever()
可用于解耦服务器实例化和服务。 如果服务器正在服务,新的 Server.is_serving() 方法返回True
。 Server 对象现在是异步上下文管理器:srv = await loop.create_server(...) async with srv: # some code # At this point, srv is closed and no longer accepts new connections.
(由 Yury Selivanov 在 :issue:`32662` 中贡献。)
loop.call_later() 返回的回调对象获得了新的 when() 方法,该方法返回一个绝对调度的回调时间戳。 (由 Andrew Svetlov 在 中提供:issue:`32741`。)
loop.create_datagram_endpoint()
方法获得了对 Unix 套接字的支持。 (由 Quentin Dawans 在 中提供:issue:`31245`。)asyncio.open_connection()
、asyncio.start_server()
函数、loop.create_connection()
、loop.create_server()
、loop.create_accepted_socket()
方法及其相应的 UNIX 套接字变体现在接受 ssl_handshake_timeout 关键字参数。 (由 Neil Aspinall 在 :issue:`29970` 中提供。)如果回调被取消,新的 Handle.cancelled() 方法返回
True
。 (由 Marat Sharafutdinov 在 中提供:issue:`31943`。)asyncio 源已转换为使用 async/await 语法。 (由 Andrew Svetlov 在 中提供:issue:`32193`。)
新的 ReadTransport.is_reading() 方法可用于确定传输的读取状态。 此外,对 ReadTransport.resume_reading() 和 ReadTransport.pause_reading() 的调用现在是幂等的。 (由 Yury Selivanov 在 :issue:`32356` 中贡献。)
接受套接字路径的循环方法现在支持传递 类路径对象 。 (由 Yury Selivanov 在 :issue:`32066` 中贡献。)
在 asyncio 中,Linux 上的 TCP 套接字现在默认设置为
TCP_NODELAY
标志。 (由 Yury Selivanov 和 Victor Stinner 在 中提供:issue:`27456`。)不再记录已取消任务中发生的异常。 (由 Yury Selivanov 在 :issue:`30508` 中贡献。)
新的
WindowsSelectorEventLoopPolicy
和WindowsProactorEventLoopPolicy
类。 (由 Yury Selivanov 在 中提供:issue:`33792`。)
几个 asyncio
API 已被 弃用 。
编译所有
compileall.compile_dir() 学习了新的 invalidation_mode 参数,可用于启用 基于哈希的 .pyc 失效。 也可以使用新的 --invalidation-mode
参数在命令行上指定失效模式。 (由 Benjamin Peterson 在 中提供:issue:`31650`。)
并发期货
ProcessPoolExecutor 和 ThreadPoolExecutor 现在支持新的 initializer 和 initargs 构造函数参数。 (由 Antoine Pitrou 在 中提供:issue:`21423`。)
ProcessPoolExecutor 现在可以通过新的 mp_context 参数获取多处理上下文。 (由 Thomas Moreau 在 中提供:issue:`31540`。)
上下文库
新的 nullcontext() 是比 ExitStack 更简单、更快的无操作上下文管理器。 (由 Jesse-Bakker 在 :issue:`10049` 中贡献。)
添加了新的 asynccontextmanager()、AbstractAsyncContextManager 和 AsyncExitStack 以补充它们的同步对应项。 (由 Jelle Zijlstra 在 :issue:`29679` 和 :issue:`30241` 以及 Alexander Mohr 和 Ilya Kulakov 在 :issue:`29302`[ X147X]。)
地穴
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` 中贡献。)
迪斯
dis() 函数现在能够反汇编嵌套代码对象(推导式、生成器表达式和嵌套函数的代码,以及用于构建嵌套类的代码)。 反汇编递归的最大深度由新的 depth 参数控制。 (由 Serhiy Storchaka 在 中提供:issue:`11822`。)
枚举
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`。)
GC
新的 gc.freeze() 函数允许冻结垃圾收集器跟踪的所有对象,并将它们从未来的收集中排除。 这可以在 POSIX fork()
调用之前使用,以使 GC 写时复制友好或加快收集速度。 新的 gc.unfreeze() 函数反转了这个操作。 此外,gc.get_freeze_count() 可用于获取冻结对象的数量。 (由李泽坤在 中提供:issue:`31558`。)
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.IPv6Network 和 ipaddress.IPv4Network 新的 subnet_of()
和 supernet_of()
方法可用于网络遏制测试。 (由 Michel Albert 和 Cheryl Sabella 在 :issue:`20825` 中贡献。)
语言环境
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`。)
多处理
新的 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`。)
数据库
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`。)
关于
可以在组范围内设置标志 re.ASCII、re.LOCALE 和 re.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.ForkingMixIn 和 socketserver.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`)
SSLSocket 和 SSLObject 不再有公共构造函数。 直接实例化从来都不是记录在案和受支持的功能。 必须使用 SSLContext 方法 wrap_socket() 和 wrap_bio() 创建实例。 (由 Christian Heimes 在 中提供:issue:`32951`)
用于设置最小和最大 TLS 协议版本的 OpenSSL 1.1 API 可用作 SSLContext.minimum_version 和 SSLContext.maximum_version。 支持的协议由几个新标志指示,例如 HAS_TLSv1_1。 (由 Christian Heimes 在 中提供:issue:`32609`。)
子流程
subprocess.run() 函数接受新的 capture_output 关键字参数。 当为 true 时,将捕获 stdout 和 stderr。 这相当于将 subprocess.PIPE 作为 stdout 和 stderr 参数传递。 (由 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 564 为 time 模块增加了六个具有纳秒级分辨率的新函数:
time.clock_gettime_ns()
time.clock_settime_ns()
time.monotonic_ns()
time.perf_counter_ns()
time.process_time_ns()
time.time_ns()
添加了新的时钟标识符:
- time.CLOCK_BOOTTIME (Linux):与 time.CLOCK_MONOTONIC 相同,除了它还包括系统暂停的任何时间。
- time.CLOCK_PROF(FreeBSD、NetBSD 和 OpenBSD):高分辨率的每进程 CPU 计时器。
- time.CLOCK_UPTIME (FreeBSD, OpenBSD): 时间,其绝对值是系统一直运行且未挂起的时间,提供准确的正常运行时间测量。
新的 time.thread_time() 和 time.thread_time_ns() 函数可用于获取每个线程的 CPU 时间测量。 (由 Antoine Pitrou 在 中提供:issue:`32025`。)
新的 time.pthread_getcpuclockid() 函数返回线程特定 CPU 时间时钟的时钟 ID。
tracemalloc
tracemalloc.Traceback 的行为更像常规回溯,将帧从最旧到最新排序。 Traceback.format() 现在接受负 limit,将结果截断到 abs(limit)
最旧的帧。 要获得旧的行为,请使用新的 most_recent_first 参数到 Traceback.format()
。 (由 Jesse Bakker 在 中提供:issue:`32121`。)
类型
新的 WrapperDescriptorType、MethodWrapperType、MethodDescriptorType 和 ClassMethodDescriptorType 类现在可用。 (由 Manuel Krebber 和 Guido van Rossum 在 :issue:`29377` 和 Serhiy Storchaka 在 :issue:`32265` 中贡献。)
新的 types.resolve_bases() 函数根据 PEP 560 的规定动态解析 MRO 条目。 (由 Ivan Levkivskyi 在 :issue:`32717` 中贡献。)
单元测试
新的 -k
命令行选项允许通过名称子字符串或类 Unix shell 模式过滤测试。 例如,python -m unittest -k foo
运行 foo_tests.SomeTest.test_something
、bar_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`。)
用户名
新的 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`。)
压缩包
函数 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`。)
新的 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`。)
结构体 PyMemberDef、PyGetSetDef、PyStructSequence_Field、[X126X,Sequence1_X29X]的字段 name
和 doc
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() 的 start 和 end 参数现在被调整为像字符串切片一样。 (由 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 模块对常用函数进行了许多显着优化:
- asyncio.get_event_loop() 函数已在 C 中重新实现,使其速度提高了 15 倍。 (由 Yury Selivanov 在 :issue:`32296` 中贡献。)
- asyncio.Future 回调管理优化。 (由 Yury Selivanov 在 :issue:`32348` 中贡献。)
asyncio.gather()
现在最多为 15% faster。 (由 Yury Selivanov 在 :issue:`32355` 中贡献。)- 当 delay 参数为零或负数时,
asyncio.sleep()
现在最多快 2 倍。 (由 Andrew Svetlov 在 :issue:`32351` 中提供。) - 降低了 asyncio 调试模式的性能开销。 (由 Antoine Pitrou 在 中提供:issue:`31970`。)
由于 PEP 560 work,typing 的导入时间减少了 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.EpollSelector、selectors.PollSelector 和 selectors.DevpollSelector 的 modify() 方法可能在 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.date 和 datetime.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 表达式(yield
和 yield 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 模块、函数和方法
异步
对 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`。)
导入库
方法 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。
穿线
dummy_threading
和 _dummy_thread
已被弃用。 不再可能在禁用线程的情况下构建 Python。 改用 线程 。 (由 Antoine Pitrou 在 中提供:issue:`31370`。)
插座
socket.htons() 和 socket.ntohs() 中的静默参数值截断已被弃用。 在 Python 的未来版本中,如果传递的参数大于 16 位,则会引发异常。 (由 Oren Milman 在 中提供:issue:`28332`。)
系统
已弃用 sys.set_coroutine_wrapper()
和 sys.get_coroutine_wrapper()
。
未记录的 sys.callstats()
函数已被弃用,并将在未来的 Python 版本中删除。 (由 Victor Stinner 在 中提供:问题:`28799`。)
不推荐使用的 C API 函数和类型
如果 Py_LIMITED_API
未设置或设置为 0x03050400
和 0x03060000
之间范围内的值,则函数 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 语言环境)作为旧的基于ASCII
的C
语言环境的替代。不再支持 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 类
Plist
、Dict
和_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.selectors
和asyncio._overlapped
。 将from asyncio import selectors
替换为import selectors
。 - 现在禁止直接实例化 ssl.SSLSocket 和 ssl.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-32
和 py -3-64
和 py -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 行为的变化
async 和 await 名称现在是保留关键字。 使用这些名称作为标识符的代码现在将引发 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 的变化
socketserver.ThreadingMixIn.server_close()
现在等待所有非守护线程完成。 将新的socketserver.ThreadingMixIn.block_on_close
类属性设置为False
以获得 3.7 之前的行为。 (由 Victor Stinner 在 :issue:`31233` 和 :issue:`33540` 中贡献。)socketserver.ForkingMixIn.server_close()
现在等待所有子进程完成。 将新的socketserver.ForkingMixIn.block_on_close
类属性设置为False
以获得 3.7 之前的行为。 (由 Victor Stinner 在 :issue:`31151` 和 :issue:`33540` 中贡献。)locale.localeconv() 函数现在在某些情况下暂时将
LC_CTYPE
语言环境设置为LC_NUMERIC
的值。 (由 Victor Stinner 在 中提供:问题:`31900`。)pkgutil.walk_packages() 如果 path 是一个字符串,现在会引发 ValueError。 以前返回一个空列表。 (由 Sanyam Khurana 在 :issue:`24744` 中提供。)
string.Formatter.format() 的格式字符串参数现在是 positional-only。 在 Python 3.5 中不推荐将其作为关键字参数传递。 (由 Serhiy Storchaka 在 中提供:issue:`29193`。)
类 http.cookies.Morsel 的属性 key、value 和 coded_value 现在是只读的。 分配给它们在 Python 3.5 中已弃用。 使用 set() 方法设置它们。 (由 Serhiy Storchaka 在 中提供:issue:`29192`。)
os.makedirs() 的 mode 参数不再影响新创建的中级目录的文件权限位。 要设置它们的文件权限位,您可以在调用
makedirs()
之前设置 umask。 (由 Serhiy Storchaka 在 :issue:`19930` 中提供。)struct.Struct.format 类型现在是 str 而不是 bytes。 (由 Victor Stinner 在 中提供:问题:`21071`。)
parse_multipart() 现在接受 encoding 和 errors 参数并返回与
FieldStorage
相同的结果:对于非文件字段,关联的值键是一个字符串列表,而不是字节。 (由 Pierre Quentel 在 中提供:issue:`29979`。)由于 socket 的内部变化,不支持在旧 Python 版本中对 socket.share 创建的套接字调用 socket.fromshare()。
BaseException 的
repr
已更改为不包括尾随逗号。 大多数异常都受此更改的影响。 (由 Serhiy Storchaka 在 中提供:issue:`30399`。)datetime.timedelta 的
repr
已更改为在输出中包含关键字参数。 (由 Utkarsh Upadhyay 在 :issue:`30302` 中贡献。)因为 shutil.rmtree() 现在是使用 os.scandir() 函数实现的,所以现在使用第一个参数
os.scandir
代替os.listdir
列出目录失败。将来可能会添加对正则表达式中嵌套集合和集合操作的支持,如 Unicode 技术标准 #18。 这将改变语法。 为了促进这种未来的变化,FutureWarning 将暂时在不明确的情况下提出。 这包括以文字
'['
开头或包含文字字符序列'--'
、'&&'
、'~~'
和'||'
的集合。 为避免警告,请使用反斜杠将它们转义。 (由 Serhiy Storchaka 在 中提供:issue:`30349`。)在可以匹配空字符串的 正则表达式 上拆分字符串的结果已更改。 例如,在
r'\s*'
上拆分现在不仅会像以前那样拆分空白字符,还会拆分所有非空白字符之前和字符串末尾之前的空字符串。 通过将模式更改为r'\s+'
,可以恢复之前的行为。 自 Python 3.5 以来,针对此类模式发出了 FutureWarning。对于同时匹配空字符串和非空字符串的模式,在其他情况下也可能会更改所有匹配项的搜索结果。 例如在字符串
'a\n\n'
中,模式r'(?m)^\s*?$'
不仅会匹配位置 2 和 3 的空字符串,还会匹配位置 2-3 的字符串'\n'
。 要仅匹配空行,模式应重写为r'(?m)^[^\S\n]*$'
。re.sub() 现在替换与前一个非空匹配相邻的空匹配。 例如
re.sub('x*', '-', 'abxd')
现在返回'-a-b--d-'
而不是'-a-b-d-'
('b' 和 'd' 之间的第一个减号替换 'x',第二个减号替换'x' 和 'd')。(由 Serhiy Storchaka 在 :issue:`25054` 和 :issue:`32308` 中贡献。)
将 re.escape() 更改为仅转义正则表达式特殊字符,而不是转义除 ASCII 字母、数字和
'_'
以外的所有字符。 (由 Serhiy Storchaka 在 中提供:issue:`29995`。)tracemalloc.Traceback 帧现在从最旧到最近排序,以与 traceback 更加一致。 (由 Jesse Bakker 在 中提供:issue:`32121`。)
在支持 socket.SOCK_NONBLOCK 或 socket.SOCK_CLOEXEC 位标志的操作系统上,socket.type 不再应用它们。 因此,像
if sock.type == socket.SOCK_STREAM
这样的检查在所有平台上都按预期工作。 (由 Yury Selivanov 在 :issue:`32331` 中贡献。)在 Windows 上,重定向标准句柄时,subprocess.Popen 的 close_fds 参数的默认值从 False 更改为 True。 如果您之前在使用具有标准 io 重定向的 subprocess.Popen 时依赖于被继承的句柄,则必须传递
close_fds=False
以保留以前的行为,或使用 STARTUPINFO.lpAttributeList[ X227X]。importlib.machinery.PathFinder.invalidate_caches() – 隐式影响 importlib.invalidate_caches() – 现在删除 sys.path_importer_cache 中设置为
None
。 (由 Brett Cannon 在 中提供:issue:`33169`。)在 asyncio,
loop.sock_recv()
,loop.sock_sendall()
,loop.sock_accept()
,loop.getaddrinfo()
,loop.getnameinfo()
已被更改为适当的协程方法来匹配他们的文档。 以前,这些方法返回 asyncio.Future 实例。 (由 Yury Selivanov 在 :issue:`32327` 中贡献。)asyncio.Server.sockets 现在返回服务器套接字内部列表的副本,而不是直接返回它。 (由 Yury Selivanov 在 :issue:`32662` 中贡献。)
Struct.format 现在是 str 实例而不是 bytes 实例。 (由 Victor Stinner 在 中提供:问题:`21071`。)
argparse 子解析器现在可以通过将
required=True
传递给 ArgumentParser.add_subparsers() 来强制执行。 (由 Anthony Sottile 在 中提供:issue:`26510`。)ast.literal_eval() 现在更严格了。 不再允许任意数字的加减。 (由 Serhiy Storchaka 在 中提供:issue:`31778`。)
Calendar.itermonthdates 现在将在日期超出
0001-01-01
到9999-12-31
范围时始终引发异常。 为了支持不能容忍此类异常的应用程序,可以使用新的 Calendar.itermonthdays3 和 Calendar.itermonthdays4。 新方法返回元组并且不受 datetime.date 支持的范围的限制。 (由 Alexander Belopolsky 在 :issue:`28292` 中提供。)collections.ChainMap 现在保留底层映射的顺序。 (由 Raymond Hettinger 在 中提供:issue:`32792`。)
如果在解释器关闭期间调用,concurrent.futures.ThreadPoolExecutor 和 concurrent.futures.ProcessPoolExecutor 的
submit()
方法现在会引发 RuntimeError。 (由 Mark Nemec 在 中提供:issue:`33097`。)configparser.ConfigParser 构造函数现在使用
read_dict()
来处理默认值,使其行为与解析器的其余部分一致。 默认字典中的非字符串键和值现在被隐式转换为字符串。 (由 James Tocknell 在 :issue:`23835` 中贡献。)删除了几个未记录的内部导入。 一个例子是
os.errno
不再可用; 直接使用import errno
代替。 请注意,即使在微型版本中,此类未记录的内部导入也可能随时被删除,恕不另行通知。
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 在许多其他问题中进一步更新)。 一些已知细节受到影响:
- PySys_AddWarnOptionUnicode() 目前不能通过嵌入应用程序使用,因为需要在调用 Py_Initialize 之前创建一个 Unicode 对象。 改用 PySys_AddWarnOption()。
- 由带有 PySys_AddWarnOption() 的嵌入应用程序添加的警告过滤器现在应该更一致地优先于解释器设置的默认过滤器
由于默认警告过滤器的配置方式发生了变化,将 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.exe
和 pythonw.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` 中贡献。)