Python 3.3 的新特性

本文介绍了 Python 3.3 相对于 3.2 的新特性。Python 3.3 于 2012 年 9 月 29 日发布。有关完整详细信息,请参阅变更日志

另请参阅

PEP 398 - Python 3.3 发布时间表

摘要 – 发布亮点

新的语法特性

  • 新的 yield from 表达式,用于生成器委托

  • 再次接受 u'unicode' 语法,用于 str 对象。

新的库模块

  • faulthandler(有助于调试底层崩溃)

  • ipaddress(表示 IP 地址和掩码的高级对象)

  • lzma(使用 XZ / LZMA 算法压缩数据)

  • unittest.mock(用模拟对象替换被测系统的一部分)

  • venv(Python 虚拟环境,类似于流行的 virtualenv 包)

新的内置特性

实现改进

显著改进的库模块

安全改进

  • 默认情况下启用哈希随机化。

请继续阅读以获取面向用户的更改的完整列表。

PEP 405: 虚拟环境

虚拟环境有助于创建单独的 Python 设置,同时共享系统范围的基础安装,以便于维护。虚拟环境有自己的一组私有站点包(即本地安装的库),并且可以选择与系统范围的站点包隔离。它们的概念和实现受流行的 virtualenv 第三方包的启发,但受益于与解释器核心的更紧密集成。

此 PEP 添加了 venv 模块以进行编程访问,以及 pyvenv 脚本以进行命令行访问和管理。Python 解释器检查 pyvenv.cfg 文件,该文件的存在表示虚拟环境目录树的根。

另请参阅

PEP 405 - Python 虚拟环境

PEP 由 Carl Meyer 编写;由 Carl Meyer 和 Vinay Sajip 实现

PEP 420: 隐式命名空间包

对不需要 __init__.py 标记文件的包目录的本机支持,并且可以自动跨多个路径段(受命名空间包的各种第三方方法的启发,如 PEP 420 中所述)

另请参阅

PEP 420 - 隐式命名空间包

PEP 由 Eric V. Smith 编写;由 Eric V. Smith 和 Barry Warsaw 实现

PEP 3118: 新的 memoryview 实现和缓冲区协议文档

PEP 3118 的实现已得到显著改进。

新的 memoryview 实现全面修复了 Py_buffer 结构中动态分配字段的所有权和生命周期问题,这些问题导致了多次崩溃报告。此外,还修复了一些对于非连续或多维输入崩溃或返回不正确结果的函数。

memoryview 对象现在具有符合 PEP-3118 的 getbufferproc(),该函数检查使用者的请求类型。添加了许多新特性,其中大多数都完全适用于非连续数组和具有子偏移的数组。

文档已更新,明确说明了导出者和使用者的责任。缓冲区请求标志分为基本标志和复合标志。解释了非连续和多维 NumPy 风格数组的内存布局。

特性

  • 现在支持 struct 模块语法中的所有本机单字符格式说明符(可以选择以“@”为前缀)。

  • 在某些限制下,cast() 方法允许更改 C 连续数组的格式和形状。

  • 支持任何数组类型的多维列表表示。

  • 支持任何数组类型的多维比较。

  • 现在,具有格式 B、b 或 c 的可哈希(只读)类型的一维 memoryview 是可哈希的。(由 Antoine Pitrou 在 bpo-13411 中贡献。)

  • 支持任何 1-D 数组类型的任意切片。例如,现在可以使用负步长以 O(1) 的时间复杂度反转 memoryview。

API 更改

  • 维度的最大数量正式限制为 64。

  • 空形状、步幅和子偏移的表示现在是一个空元组,而不是 None

  • 现在,访问格式为“B”(无符号字节)的 memoryview 元素会返回一个整数(符合 struct 模块语法)。要返回字节对象,必须首先将视图转换为“c”。

  • memoryview 比较现在使用操作数的逻辑结构,并按值比较所有数组元素。支持 struct 模块语法中的所有格式字符串。仍然允许使用无法识别的格式字符串的视图,但无论视图内容如何,它们始终被比较为不相等。

  • 有关更多更改,请参阅构建和 C API 更改移植 C 代码

(由 Stefan Krah 在 bpo-10181 中贡献。)

另请参阅

PEP 3118 - 修订缓冲区协议

PEP 393: 灵活的字符串表示

Unicode 字符串类型已更改为支持多种内部表示形式,具体取决于所表示字符串中具有最大 Unicode 序号的字符(1、2 或 4 字节)。这允许在常见情况下进行空间高效的表示,但可以在所有系统上访问完整的 UCS-4。为了与现有 API 兼容,可能会并行存在多种表示形式;随着时间的推移,这种兼容性应该逐步淘汰。

在 Python 方面,此更改应该没有任何缺点。

在 C API 方面,PEP 393 是完全向后兼容的。旧版 API 至少应保留五年。使用旧版 API 的应用程序不会完全受益于内存的减少,或者更糟糕的是,可能会使用更多的内存,因为 Python 可能需要维护每个字符串的两个版本(旧版格式和新的高效存储)。

功能

PEP 393 引入的更改如下

  • Python 现在始终支持完整的 Unicode 代码点范围,包括非 BMP 代码点(即从 U+0000U+10FFFF)。窄版本和宽版本之间的区别不再存在,Python 现在的行为类似于宽版本,即使在 Windows 下也是如此。

  • 随着窄版本的消亡,特定于窄版本的问题也已得到修复,例如

    • len() 现在对于非 BMP 字符始终返回 1,因此 len('\U0010FFFF') == 1

    • 代理对不会在字符串字面量中重新组合,因此 '\uDBFF\uDFFF' != '\U0010FFFF'

    • 索引或切片非 BMP 字符会返回期望的值,因此 '\U0010FFFF'[0] 现在返回 '\U0010FFFF',而不是 '\uDBFF'

    • 标准库中的所有其他函数现在都可以正确处理非 BMP 代码点。

  • sys.maxunicode 的值现在始终为 1114111(十六进制为 0x10FFFF)。为了向后兼容,PyUnicode_GetMax() 函数仍然返回 0xFFFF0x10FFFF,并且不应将其与新的 Unicode API 一起使用(请参阅 bpo-13054)。

  • ./configure 标志 --with-wide-unicode 已被删除。

性能和资源使用

Unicode 字符串的存储现在取决于字符串中的最高代码点

  • 纯 ASCII 和 Latin1 字符串(U+0000-U+00FF)每个代码点使用 1 个字节;

  • BMP 字符串(U+0000-U+FFFF)每个代码点使用 2 个字节;

  • 非 BMP 字符串(U+10000-U+10FFFF)每个代码点使用 4 个字节。

最终的结果是,对于大多数应用程序,字符串存储的内存使用量应该会显著减少——特别是与以前的宽 Unicode 版本相比——因为在许多情况下,即使在国际环境中,字符串也将是纯 ASCII 字符串(因为许多字符串存储非人类语言数据,例如 XML 片段、HTTP 标头、JSON 编码的数据等)。我们还希望,出于相同的原因,它将提高非平凡应用程序的 CPU 缓存效率。在 Django 基准测试中,Python 3.3 的内存使用量比 Python 3.2 小两到三倍,并且比 Python 2.7 好一点(有关详细信息,请参阅 PEP)。

另请参阅

PEP 393 - 灵活的字符串表示

由 Martin von Löwis 编写的 PEP;由 Torsten Becker 和 Martin von Löwis 实现。

PEP 397:Windows 的 Python 启动器

Python 3.3 Windows 安装程序现在包含一个 py 启动器应用程序,该应用程序可以用来以与版本无关的方式启动 Python 应用程序。

双击 *.py 文件时会隐式调用此启动器。如果系统上只安装了一个 Python 版本,则该版本将用于运行该文件。如果安装了多个版本,则默认情况下使用最新版本,但这可以通过在 Python 脚本中包含 Unix 风格的“shebang 行”来覆盖。

也可以从命令行显式使用启动器作为 py 应用程序。运行 py 遵循与隐式启动脚本相同的版本选择规则,但是可以通过传递适当的参数来选择更具体的版本(例如,当也安装了 Python 2 时,使用 -3 来请求 Python 3,或者当安装了更新的版本时,使用 -2.6 来明确请求更早版本的 Python)。

除了启动器外,Windows 安装程序现在还包括一个选项,可将新安装的 Python 添加到系统 PATH 中。(由 Brian Curtin 在 bpo-3561 中贡献。)

另请参阅

PEP 397 - Windows 的 Python 启动器

由 Mark Hammond 和 Martin v. Löwis 编写的 PEP;由 Vinay Sajip 实现。

启动器文档: Windows 的 Python 启动器

安装程序 PATH 修改: 查找 Python 可执行文件

PEP 3151:重新设计 OS 和 IO 异常层次结构

现在,由操作系统错误引发的异常层次结构既简化又更加精细。

您不必再担心在 OSErrorIOErrorEnvironmentErrorWindowsErrormmap.errorsocket.errorselect.error 之间选择适当的异常类型。所有这些异常类型现在只有一个:OSError。其他名称保留为别名,以实现兼容性。

此外,现在更容易捕获特定的错误情况。您可以捕获适当的 OSError 子类,而不是检查 errno 属性(或 args[0])以查找 errno 模块中的特定常量。可用的子类如下

并且 ConnectionError 本身具有更精细的子类

由于有了新的异常,现在可以避免 errno 的常见用法。例如,为 Python 3.2 编写的以下代码

from errno import ENOENT, EACCES, EPERM

try:
    with open("document.txt") as f:
        content = f.read()
except IOError as err:
    if err.errno == ENOENT:
        print("document.txt file is missing")
    elif err.errno in (EACCES, EPERM):
        print("You are not allowed to read document.txt")
    else:
        raise

现在可以编写,而无需 errno 导入和手动检查异常属性

try:
    with open("document.txt") as f:
        content = f.read()
except FileNotFoundError:
    print("document.txt file is missing")
except PermissionError:
    print("You are not allowed to read document.txt")

另请参阅

PEP 3151 - 重新设计 OS 和 IO 异常层次结构

由 Antoine Pitrou 编写和实现的 PEP

PEP 380:委托给子生成器的语法

PEP 380 添加了 yield from 表达式,允许 生成器 将其部分操作委托给另一个生成器。这允许将包含 yield 的代码段分解出来并放置在另一个生成器中。此外,允许子生成器返回一个值,并且该值可用于委托生成器。

尽管主要设计用于委托给子生成器,但 yield from 表达式实际上允许委托给任意子迭代器。

对于简单的迭代器,yield from iterable 本质上只是 for item in iterable: yield item 的缩写形式。

>>> def g(x):
...     yield from range(x, 0, -1)
...     yield from range(x)
...
>>> list(g(5))
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4]

然而,与普通循环不同,yield from 允许子生成器直接从调用作用域接收发送值和抛出值,并将最终值返回给外部生成器。

>>> def accumulate():
...     tally = 0
...     while 1:
...         next = yield
...         if next is None:
...             return tally
...         tally += next
...
>>> def gather_tallies(tallies):
...     while 1:
...         tally = yield from accumulate()
...         tallies.append(tally)
...
>>> tallies = []
>>> acc = gather_tallies(tallies)
>>> next(acc)  # Ensure the accumulator is ready to accept values
>>> for i in range(4):
...     acc.send(i)
...
>>> acc.send(None)  # Finish the first tally
>>> for i in range(5):
...     acc.send(i)
...
>>> acc.send(None)  # Finish the second tally
>>> tallies
[6, 10]

推动此更改的主要原则是,即使是那些设计为与 sendthrow 方法一起使用的生成器,也可以像将一个大型函数拆分成多个子函数一样轻松地拆分成多个子生成器。

另请参阅

PEP 380 - 委托给子生成器的语法

PEP 由 Greg Ewing 撰写;由 Greg Ewing 实现,由 Renaud Blanch、Ryan Kelly 和 Nick Coghlan 集成到 3.3 版本中;由 Zbigniew Jędrzejewski-Szmek 和 Nick Coghlan 编写文档。

PEP 409:抑制异常上下文

PEP 409 引入了新的语法,允许禁用链式异常上下文的显示。这使得在异常类型之间转换的应用程序中可以显示更清晰的错误消息。

>>> class D:
...     def __init__(self, extra):
...         self._extra_attributes = extra
...     def __getattr__(self, attr):
...         try:
...             return self._extra_attributes[attr]
...         except KeyError:
...             raise AttributeError(attr) from None
...
>>> D({}).x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in __getattr__
AttributeError: x

如果没有 from None 后缀来抑制原因,默认情况下将显示原始异常。

>>> class C:
...     def __init__(self, extra):
...         self._extra_attributes = extra
...     def __getattr__(self, attr):
...         try:
...             return self._extra_attributes[attr]
...         except KeyError:
...             raise AttributeError(attr)
...
>>> C({}).x
Traceback (most recent call last):
  File "<stdin>", line 6, in __getattr__
KeyError: 'x'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in __getattr__
AttributeError: x

不会丢失任何调试功能,因为如果需要,原始异常上下文仍然可用(例如,如果中间库错误地抑制了有价值的底层细节)。

>>> try:
...     D({}).x
... except AttributeError as exc:
...     print(repr(exc.__context__))
...
KeyError('x',)

另请参阅

PEP 409 - 抑制异常上下文

PEP 由 Ethan Furman 撰写;由 Ethan Furman 和 Nick Coghlan 实现。

PEP 414:显式 Unicode 字面量

为了简化从 Python 2 到大量使用 Unicode 字面量的 Unicode 感知 Python 应用程序的过渡,Python 3.3 再次支持字符串字面量的 “u” 前缀。此前缀在 Python 3 中没有语义意义,它仅用于减少迁移到 Python 3 中的纯机械更改的数量,使开发人员更容易专注于更重要的语义更改(例如,更严格地默认分离二进制数据和文本数据)。

另请参阅

PEP 414 - 显式 Unicode 字面量

PEP 由 Armin Ronacher 撰写。

PEP 3155:类和函数的限定名称

函数和类对象有一个新的 __qualname__ 属性,表示从模块顶层到其定义的“路径”。对于全局函数和类,这与 __name__ 相同。对于其他函数和类,它提供了关于它们实际定义位置以及如何从全局作用域访问它们的更好信息。

非绑定方法的示例

>>> class C:
...     def meth(self):
...         pass
...
>>> C.meth.__name__
'meth'
>>> C.meth.__qualname__
'C.meth'

嵌套类的示例

>>> class C:
...     class D:
...         def meth(self):
...             pass
...
>>> C.D.__name__
'D'
>>> C.D.__qualname__
'C.D'
>>> C.D.meth.__name__
'meth'
>>> C.D.meth.__qualname__
'C.D.meth'

嵌套函数的示例

>>> def outer():
...     def inner():
...         pass
...     return inner
...
>>> outer().__name__
'inner'
>>> outer().__qualname__
'outer.<locals>.inner'

这些对象的字符串表示形式也已更改,以包含新的、更精确的信息。

>>> str(C.D)
"<class '__main__.C.D'>"
>>> str(C.D.meth)
'<function C.D.meth at 0x7f46b9fe31e0>'

另请参阅

PEP 3155 - 类和函数的限定名称

PEP 由 Antoine Pitrou 撰写和实现。

PEP 412:密钥共享字典

用于存储对象属性的字典现在能够在彼此之间共享部分内部存储(即,存储键及其各自哈希值的部分)。这减少了创建大量非内置类型实例的程序的内存消耗。

另请参阅

PEP 412 - 密钥共享字典

PEP 由 Mark Shannon 撰写和实现。

PEP 362:函数签名对象

一个新的函数 inspect.signature() 使对 python 可调用对象的内省变得容易且直接。支持广泛的可调用对象:python 函数(带或不带装饰器)、类和 functools.partial() 对象。新的类 inspect.Signatureinspect.Parameterinspect.BoundArguments 保存有关调用签名的信息,例如,注解、默认值、参数类型和绑定参数,这大大简化了编写装饰器以及任何验证或修改调用签名或参数的代码。

另请参阅

PEP 362: - 函数签名对象

PEP 由 Brett Cannon、Yury Selivanov、Larry Hastings、Jiwon Seo 撰写;由 Yury Selivanov 实现。

PEP 421:添加 sys.implementation

sys 模块上的一个新属性公开了当前正在运行的解释器实现的特定细节。sys.implementation 上的初始属性集为 nameversionhexversioncache_tag

sys.implementation 的目的是将标准库使用的特定于实现的数据整合到一个命名空间中。这使得不同的 Python 实现可以更容易地共享单个标准库代码库。在其初始状态下,sys.implementation 仅保留一小部分特定于实现的数据。随着时间的推移,该比例将发生变化,以使标准库更具可移植性。

改进标准库可移植性的一个例子是 cache_tag。从 Python 3.3 开始,sys.implementation.cache_tagimportlib 用来支持 PEP 3147 的合规性。任何使用 importlib 作为其内置导入系统的 Python 实现都可以使用 cache_tag 来控制模块的缓存行为。

SimpleNamespace

sys.implementation 的实现还为 Python 引入了一个新类型:types.SimpleNamespace。与基于映射的命名空间(如 dict)相比,SimpleNamespace 是基于属性的,如 object。但是,与 object 不同,SimpleNamespace 实例是可写的。这意味着您可以通过普通的属性访问来添加、删除和修改命名空间。

另请参阅

PEP 421 - 添加 sys.implementation

PEP 由 Eric Snow 撰写和实现。

使用 importlib 作为导入的实现

bpo-2377 - 将 __import__ 替换为 importlib.__import__ bpo-13959 - 在纯 Python 中重新实现 imp 的部分 bpo-14605 - 使导入机制明确 bpo-14646 - 要求加载器设置 __loader__ 和 __package__

现在,__import__() 函数由 importlib.__import__() 提供支持。这项工作完成了 PEP 302 的“第二阶段”。此更改带来了多重好处。首先,它允许更多用于支持导入的机制被公开,而不是隐式地隐藏在 C 代码中。它还为所有支持 Python 3.3 的 Python 虚拟机提供了一个统一的实现,有助于结束导入语义中任何虚拟机特定的偏差。最后,它简化了导入的维护,允许未来进行扩展。

对于普通用户来说,语义上应该没有明显的改变。对于那些目前操作导入或以编程方式调用导入的代码,可能需要的代码更改将在本文档的 移植 Python 代码 部分中介绍。

新的 API

这项工作的一大好处是公开了使导入语句工作的原理。这意味着曾经隐式的各种导入器现在都完全作为 importlib 包的一部分公开出来。

定义在 importlib.abc 中的抽象基类已经扩展,通过引入 importlib.abc.MetaPathFinderimportlib.abc.PathEntryFinder,来正确区分 元路径查找器路径条目查找器。旧的 importlib.abc.Finder 抽象基类现在仅为了向后兼容性而提供,并且不强制任何方法要求。

就查找器而言,importlib.machinery.FileFinder 公开了用于搜索模块的源文件和字节码文件的机制。以前,此类是 sys.path_hooks 的隐式成员。

对于加载器,新的抽象基类 importlib.abc.FileLoader 有助于编写一个使用文件系统作为模块代码存储机制的加载器。现在可以直接使用源文件的加载器 (importlib.machinery.SourceFileLoader)、无源字节码文件的加载器 (importlib.machinery.SourcelessFileLoader) 和扩展模块的加载器 (importlib.machinery.ExtensionFileLoader)。

现在,ImportError 具有 namepath 属性,当有相关数据提供时会设置这些属性。现在,导入失败的消息还将提供模块的完整名称,而不仅仅是模块名称的末尾部分。

现在,importlib.invalidate_caches() 函数将调用缓存在 sys.path_importer_cache 中的所有查找器上的同名方法,以帮助清理任何必要的存储状态。

可见的更改

有关代码的潜在所需更改,请参阅 移植 Python 代码 部分。

除了 importlib 现在公开的内容之外,导入还有其他可见的更改。最大的变化是 sys.meta_pathsys.path_hooks 现在存储导入使用的所有元路径查找器和路径条目钩子。以前,查找器是隐式的并隐藏在导入的 C 代码中,而不是直接暴露出来。这意味着现在可以轻松地删除或更改各种查找器的顺序以满足需求。

另一个变化是,所有模块都有一个 __loader__ 属性,用于存储创建模块的加载器。 PEP 302 已经更新,使这个属性对于加载器来说是强制实现的,因此在未来,一旦第三方加载器更新后,人们就可以依赖该属性的存在。但在那时之前,导入是在加载后设置模块的。

加载器现在还需要根据 PEP 366 设置 __package__ 属性。同样,导入本身已经为 importlib 中的所有加载器设置了此属性,并且导入本身是在加载后设置该属性的。

当在 sys.path_hooks 上找不到查找器时,现在会将 None 插入到 sys.path_importer_cache 中。由于 imp.NullImporter 没有直接在 sys.path_hooks 上公开,因此不能再依赖它始终可用作表示未找到查找器的值。

所有其他更改都与语义更改有关,在为 Python 3.3 更新代码时应考虑这些更改,因此应在本文档的 移植 Python 代码 部分中阅读相关信息。

(由 Brett Cannon 实现)

其他语言更改

对核心 Python 语言进行的一些较小的更改是

  • 增加了对 Unicode 名称别名和命名序列的支持。现在,unicodedata.lookup()'\N{...}' 都解析名称别名,并且 unicodedata.lookup() 也解析命名序列。

    (由 Ezio Melotti 在 bpo-12753 中贡献。)

  • Unicode 数据库更新到 UCD 版本 6.1.0

  • 现在,对 range() 对象进行相等比较会返回一个结果,反映由这些 range 对象生成的底层序列的相等性。(bpo-13201

  • 现在,bytesbytearray 对象的 count()find()rfind()index()rindex() 方法接受一个介于 0 和 255 之间的整数作为它们的第一个参数。

    (由 Petri Lehtinen 在 bpo-12170 中贡献。)

  • 现在,bytesbytearray 对象的 rjust()ljust()center() 方法接受一个 bytearray 作为 fill 参数。(由 Petri Lehtinen 在 bpo-12380 中贡献。)

  • 新的方法已添加到 listbytearraycopy()clear() (bpo-10516)。因此,MutableSequence 现在也定义了一个 clear() 方法 (bpo-11388)。

  • 原始字节字面值现在可以写作 rb"..." 以及 br"..."

    (由 Antoine Pitrou 在 bpo-13748 中贡献。)

  • dict.setdefault() 现在只对给定的键执行一次查找,使其在与内置类型一起使用时具有原子性。

    (由 Filip Gruszczyński 在 bpo-13521 中贡献。)

  • 当函数调用与函数签名不匹配时产生的错误消息已得到显著改进。

    (由 Benjamin Peterson 贡献。)

更细粒度的导入锁

之前的 CPython 版本始终依赖于全局导入锁。这导致了意想不到的麻烦,例如当导入模块会导致在另一个线程中执行代码作为副作用时,会出现死锁。有时会采用笨拙的解决方法,例如 PyImport_ImportModuleNoBlock() C API 函数。

在 Python 3.3 中,导入模块会采用每个模块的锁。这可以正确地序列化从多个线程导入给定模块的操作(防止暴露不完全初始化的模块),同时消除上述麻烦。

(由 Antoine Pitrou 在 bpo-9260 中贡献。)

内置函数和类型

  • open() 获取一个新的 *opener* 参数:文件对象的底层文件描述符随后通过使用 ( *file* , *flags* ) 调用 *opener* 来获得。它可以用于使用自定义标志,例如 os.O_CLOEXEC。添加了 'x' 模式:以独占创建方式打开,如果文件已存在则失败。

  • print():添加了 *flush* 关键字参数。如果 *flush* 关键字参数为 true,则强制刷新流。

  • hash():默认启用哈希随机化,请参阅 object.__hash__()PYTHONHASHSEED

  • str 类型获取一个新的 casefold() 方法:返回字符串的 casefolded 副本,casefolded 字符串可用于不区分大小写的匹配。例如,'ß'.casefold() 返回 'ss'

  • 序列文档已进行了大量重写,以更好地解释二进制/文本序列的区别,并为各个内置序列类型提供特定的文档部分 (bpo-4966)。

新模块

faulthandler

这个新的调试模块 faulthandler 包含一些函数,用于在发生故障(例如段错误)、超时后或在用户信号上显式转储 Python 回溯信息。调用 faulthandler.enable() 以安装 SIGSEGVSIGFPESIGABRTSIGBUSSIGILL 信号的故障处理程序。您还可以通过设置 PYTHONFAULTHANDLER 环境变量或使用 -X faulthandler 命令行选项在启动时启用它们。

在 Linux 上发生段错误的示例

$ python -q -X faulthandler
>>> import ctypes
>>> ctypes.string_at(0)
Fatal Python error: Segmentation fault

Current thread 0x00007fb899f39700:
  File "/home/python/cpython/Lib/ctypes/__init__.py", line 486 in string_at
  File "<stdin>", line 1 in <module>
Segmentation fault

ipaddress

新的 ipaddress 模块提供了创建和操作表示 IPv4 和 IPv6 地址、网络和接口(即与特定 IP 子网关联的 IP 地址)的对象的工具。

(由 Google 和 Peter Moody 在 PEP 3144 中贡献。)

lzma

新添加的 lzma 模块使用 LZMA 算法提供数据压缩和解压缩,包括对 .xz.lzma 文件格式的支持。

(由 Nadeem Vawda 和 Per Øyvind Karlsen 在 bpo-6715 中贡献。)

改进的模块

abc

改进了对包含与抽象方法组合的描述符的抽象基类的支持。现在声明抽象描述符的推荐方法是将 __isabstractmethod__ 作为动态更新的属性提供。内置描述符已相应更新。

(由 Darren Dale 在 bpo-11610 中贡献。)

abc.ABCMeta.register() 现在返回已注册的子类,这意味着它现在可以用作类装饰器 (bpo-10868)。

array

array 模块使用 qQ 类型代码支持 long long 类型。

(由 Oren Tirosh 和 Hirokazu Yamamoto 在 bpo-1172711 中贡献。)

base64

现在,base64 现代接口的解码函数接受仅 ASCII 的 Unicode 字符串。例如,base64.b64decode('YWJj') 返回 b'abc'。(由 Catalin Iacob 在 bpo-13641 中贡献。)

binascii

除了通常接受的二进制对象外,a2b_ 函数现在也都接受仅包含 ASCII 字符的字符串作为输入。(由 Antoine Pitrou 在 bpo-13637 中贡献。)

bz2

bz2 模块已从头开始重写。在此过程中,添加了一些新功能

  • 新的 bz2.open() 函数:以二进制或文本模式打开 bzip2 压缩文件。

  • bz2.BZ2File 现在可以通过其构造函数的 fileobj 参数从任意类似文件的对象读取和写入。

    (由 Nadeem Vawda 在 bpo-5863 中贡献。)

  • bz2.BZ2Filebz2.decompress() 现在可以解压缩多流输入(例如,由 pbzip2 工具生成的输入)。bz2.BZ2File 现在也可以使用 'a' (追加)模式来创建这种类型的文件。

    (由 Nir Aides 在 bpo-1625 中贡献。)

  • bz2.BZ2File 现在实现了所有 io.BufferedIOBase API,除了 detach()truncate() 方法。

codecs

mbcs 编解码器已被重写,以便在所有 Windows 版本上正确处理 replaceignore 错误处理程序。mbcs 编解码器现在支持所有错误处理程序,而不仅仅是 replace 进行编码和 ignore 进行解码。

添加了一个新的仅限 Windows 的编解码器:cp65001bpo-13216)。它是 Windows 代码页 65001(Windows UTF-8,CP_UTF8)。例如,如果控制台输出代码页设置为 cp65001(例如,使用 chcp 65001 命令),则 sys.stdout 会使用它。

多字节 CJK 解码器现在可以更快地重新同步。它们只会忽略无效字节序列的第一个字节。例如,b'\xff\n'.decode('gb2312', 'replace') 现在会在替换字符后返回一个 \n

bpo-12016

增量 CJK 编解码器编码器不再在每次调用其 encode() 方法时重置。例如

>>> import codecs
>>> encoder = codecs.getincrementalencoder('hz')('strict')
>>> b''.join(encoder.encode(x) for x in '\u52ff\u65bd\u65bc\u4eba\u3002 Bye.')
b'~{NpJ)l6HK!#~} Bye.'

此示例在旧版本的 Python 中给出 b'~{Np~}~{J)~}~{l6~}~{HK~}~{!#~} Bye.'

bpo-12100

unicode_internal 编解码器已被弃用。

collections

添加了一个新的 ChainMap 类,以允许将多个映射视为一个单元。(由 Raymond Hettinger 为 bpo-11089 编写,并在 bpo-11297 中公开发布。)

抽象基类已移动到新的 collections.abc 模块中,以更好地区分抽象集合类和具体集合类。collections 模块中仍然存在 ABC 的别名,以保留现有的导入。(bpo-11085

Counter 类现在支持一元 +- 运算符,以及就地运算符 +=-=|=&=。(由 Raymond Hettinger 在 bpo-13121 中贡献。)

contextlib

ExitStack 现在为以编程方式操作上下文管理器和类似的清理功能提供了坚实的基础。与之前的 contextlib.nested API(已弃用并删除)不同,新的 API 旨在正确工作,无论上下文管理器是在其 __init__ 方法(例如,文件对象)还是在其 __enter__ 方法(例如,来自 threading 模块的同步对象)中获取其资源。

bpo-13585

crypt

crypt 模块添加 salt 和模块化 crypt 格式(哈希方法)以及 mksalt() 函数。

bpo-10924

curses

  • 如果 curses 模块链接到 ncursesw 库,则在传递 Unicode 字符串或字符时使用 Unicode 函数(例如 waddwstr()),否则使用字节函数(例如 waddstr())。

  • 使用区域设置编码而不是 utf-8 来编码 Unicode 字符串。

  • curses.window 有一个新的 curses.window.encoding 属性。

  • curses.window 类有一个新的 get_wch() 方法来获取宽字符

  • curses 模块有一个新的 unget_wch() 函数,用于推送一个宽字符,以便下一个 get_wch() 将返回它

(由 Iñigo Serna 在 bpo-6755 中贡献。)

datetime

decimal

bpo-7652 - 集成快速本机十进制算术。

由 Stefan Krah 编写的 C 模块和 libmpdec。

十进制模块的新 C 版本集成了高速 libmpdec 库,用于任意精度正确舍入的十进制浮点算术。libmpdec 符合 IBM 的通用十进制算术规范。

性能提升幅度从数据库应用的 10 倍到数值密集型应用的 100 倍不等。这些数字是十进制浮点运算中使用的标准精度所期望的收益。由于精度是用户可配置的,因此确切的数字可能会有所不同。例如,在整数大数算术中,差异可能明显更大。

下表旨在作为说明。基准测试可在 https://www.bytereef.org/mpdecimal/quickstart.html 获取。

decimal.py

_decimal

加速

pi

42.02秒

0.345秒

120倍

telco

172.19秒

5.68秒

30倍

psycopg

3.57秒

0.29秒

12倍

特性

  • FloatOperation 信号可以选择性地为混合浮点数和十进制数启用更严格的语义。

  • 如果 Python 在编译时没有启用线程,则 C 版本会自动禁用昂贵的线程局部上下文机制。在这种情况下,变量 HAVE_THREADS 将被设置为 False

API 更改

  • C 模块具有以下上下文限制,具体取决于机器架构

    32 位

    64 位

    MAX_PREC

    425000000

    999999999999999999

    MAX_EMAX

    425000000

    999999999999999999

    MIN_EMIN

    -425000000

    -999999999999999999

  • 在上下文模板(DefaultContextBasicContextExtendedContext)中,EmaxEmin 的幅度已更改为 999999

  • decimal.py 中的 Decimal 构造函数不遵守上下文限制,并精确转换具有任意指数或精度的值。由于 C 版本具有内部限制,因此使用以下方案:如果可能,则精确转换值,否则引发 InvalidOperation 异常,结果为 NaN。在后一种情况下,始终可以使用 create_decimal() 以获得舍入或不精确的值。

  • decimal.py 中的幂函数始终正确舍入。在 C 版本中,它根据正确舍入的 exp()ln() 函数定义,但最终结果仅“几乎始终正确舍入”。

  • 在 C 版本中,包含信号的上下文字典是 MutableMapping。出于速度原因,flagstraps 始终引用初始化上下文时使用的同一个 MutableMapping。如果分配了新的信号字典,flagstraps 将使用新值更新,但它们不引用 RHS 字典。

  • 为了使 Python 和 C 版本具有通用的交换格式,对 Context 进行 pickle 操作会产生不同的输出。

  • Context 构造函数中的参数顺序已更改,以匹配 repr() 显示的顺序。

  • quantize() 方法中的 watchexp 参数已弃用。

电子邮件

策略框架

电子邮件包现在有一个 policy 框架。Policy 是一个具有多个方法和属性的对象,用于控制电子邮件包的行为。Python 3.3 的主要策略是 Compat32 策略,该策略提供与 Python 3.2 中电子邮件包的向后兼容性。当电子邮件消息被 parser 解析时,或者当创建 Message 对象时,或者当使用 generator 序列化电子邮件时,可以指定 policy。除非被覆盖,否则传递给 parser 的策略会被 parser 创建的所有 Message 对象和子对象继承。默认情况下,generator 将使用它正在序列化的 Message 对象的策略。默认策略是 compat32

所有 policy 对象实现的最少控制集是

max_line_length

当序列化 Message 时,单个行可能具有的最大长度,不包括行分隔符字符。默认为 78。

linesep

当序列化 Message 时,用于分隔单个行的字符。默认为 \n

cte_type

7bit8bit8bit 仅适用于 Bytes generator,表示在协议允许的情况下(或在原始输入中存在的情况下)可以使用非 ASCII 字符。

raise_on_defect

导致 parser 在遇到缺陷时引发错误,而不是将它们添加到 Message 对象的 defects 列表中。

使用策略对象的 clone() 方法创建具有新设置的新策略实例。clone 将上述任何控件作为关键字参数。调用中未指定的任何控件都保留其默认值。因此,您可以创建一个像这样使用 \r\n 行分隔符字符的策略

mypolicy = compat32.clone(linesep='\r\n')

可以使用策略来简化应用程序所需的格式的消息生成。无需记住在所有调用 generator 的地方指定 linesep='\r\n',您可以在设置 parserMessage 使用的策略时指定一次,无论您的程序使用哪个来创建 Message 对象。另一方面,如果您需要生成多种形式的消息,您仍然可以在相应的 generator 调用中指定参数。或者,您可以为不同的情况使用自定义策略实例,并在创建 generator 时传入这些实例。

带有新标头 API 的临时策略

尽管策略框架本身就很有价值,但引入它的主要动机是允许创建新的策略,以一种为不使用新策略的用户保持向后兼容性的方式,为电子邮件包实现新功能。由于新策略引入了新的 API,我们在 Python 3.3 中将其作为临时策略发布。如果核心开发人员认为有必要,可能会发生向后不兼容的更改(包括删除代码)。

新的策略是 EmailPolicy 的实例,并添加了以下附加控制:

refold_source

控制由parser解析的标头是否由generator重新折叠。它可以是 nonelongall。默认值为 long,这意味着源标头中行长度超过 max_line_length 的将被重新折叠。none 表示没有行被重新折叠,而 all 表示所有行都被重新折叠。

header_factory

一个可调用对象,它接受一个 namevalue 并生成一个自定义标头对象。

header_factory 是新策略提供的关键新功能。当使用新的策略之一时,从 Message 对象检索的任何标头都是由 header_factory 生成的对象,并且任何时候你在 Message 上设置标头时,它都会成为由 header_factory 生成的对象。所有此类标头对象都有一个等于标头名称的 name 属性。地址和日期标头具有额外的属性,使你可以访问标头的解析数据。这意味着你现在可以这样做:

>>> m = Message(policy=SMTP)
>>> m['To'] = 'Éric <[email protected]>'
>>> m['to']
'Éric <[email protected]>'
>>> m['to'].addresses
(Address(display_name='Éric', username='foo', domain='example.com'),)
>>> m['to'].addresses[0].username
'foo'
>>> m['to'].addresses[0].display_name
'Éric'
>>> m['Date'] = email.utils.localtime()
>>> m['Date'].datetime
datetime.datetime(2012, 5, 25, 21, 39, 24, 465484, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000), 'EDT'))
>>> m['Date']
'Fri, 25 May 2012 21:44:27 -0400'
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <[email protected]>
Date: Fri, 25 May 2012 21:44:27 -0400

你会注意到,当消息被序列化时,Unicode 显示名称会自动编码为 utf-8,但当直接访问标头时,你会获得 Unicode 版本。这消除了处理 email.header decode_header()make_header() 函数的任何需要。

你也可以从各个部分创建地址

>>> m['cc'] = [Group('pals', [Address('Bob', 'bob', 'example.com'),
...                           Address('Sally', 'sally', 'example.com')]),
...            Address('Bonzo', addr_spec='[email protected]')]
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <[email protected]>
Date: Fri, 25 May 2012 21:44:27 -0400
cc: pals: Bob <[email protected]>, Sally <[email protected]>;, Bonzo <[email protected]>

解码为 Unicode 是自动完成的

>>> m2 = message_from_string(str(m))
>>> m2['to']
'Éric <[email protected]>'

当你解析消息时,你可以使用标头对象的 addressesgroups 属性来访问组和单个地址

>>> m2['cc'].addresses
(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com'), Address(display_name='Bonzo', username='bonz', domain='laugh.com'))
>>> m2['cc'].groups
(Group(display_name='pals', addresses=(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com')), Group(display_name=None, addresses=(Address(display_name='Bonzo', username='bonz', domain='laugh.com'),))

总而言之,如果你使用新的策略之一,标头操作的工作方式应该如下:你的应用程序使用 Unicode 字符串,而电子邮件包透明地将 Unicode 编码和解码为 RFC 标准内容传输编码,反之亦然。

其他 API 更改

新的 BytesHeaderParser,添加到 parser 模块以补充 HeaderParser 并完成 Bytes API。

新的实用函数

ftplib

  • ftplib.FTP 现在接受一个 source_address 关键字参数,以指定在创建传出套接字时在绑定调用中用作源地址的 (host, port)。(由 Giampaolo Rodolà 在 bpo-8594 中贡献。)

  • FTP_TLS 类现在提供一个新的 ccc() 函数,用于将控制通道恢复为纯文本。这对于利用那些知道如何使用非安全 FTP 处理 NAT 而无需打开固定端口的防火墙很有用。(由 Giampaolo Rodolà 在 bpo-12139 中贡献。)

  • 添加了 ftplib.FTP.mlsd() 方法,该方法提供了可解析的目录列表格式,并弃用了 ftplib.FTP.nlst()ftplib.FTP.dir()。(由 Giampaolo Rodolà 在 bpo-11072 中贡献。)

functools

functools.lru_cache() 装饰器现在接受一个 typed 关键字参数(默认为 False),以确保它在单独的缓存槽中缓存比较相等的不同类型的值。(由 Raymond Hettinger 在 bpo-13227 中贡献。)

gc

现在可以使用新的 callbacks 列表来注册在垃圾回收器进行回收之前和之后调用的回调。

hmac

添加了一个新的 compare_digest() 函数,以防止通过时间分析对摘要进行侧信道攻击。(由 Nick Coghlan 和 Christian Heimes 在 bpo-15061 中贡献。)

http

http.server.BaseHTTPRequestHandler 现在会缓冲头部信息,并在调用 end_headers() 时一次性写入所有头部信息。新的方法 flush_headers() 可用于直接管理何时发送累积的头部信息。(由 Andrew Schaaf 在 bpo-3709 中贡献。)

http.server 现在生成有效的 HTML 4.01 strict 输出。(由 Ezio Melotti 在 bpo-13295 中贡献。)

http.client.HTTPResponse 现在具有 readinto() 方法,这意味着它可以被用作 io.RawIOBase 类。(由 John Kuhn 在 bpo-13464 中贡献。)

html

html.parser.HTMLParser 现在能够解析破损的标记,而不会引发错误,因此构造函数的 strict 参数和 HTMLParseError 异常现在已被弃用。 解析破损标记的能力是大量错误修复的结果,这些修复也适用于 Python 2.7/3.2 的最新错误修复版本。(由 Ezio Melotti 在 bpo-15114bpo-14538, bpo-13993, bpo-13960, bpo-13358, bpo-1745761, bpo-755670, bpo-13357, bpo-12629, bpo-1200313, bpo-670664, bpo-13273, bpo-12888, bpo-7311 中贡献。)

一个新的 html5 字典,它将 HTML5 命名的字符引用映射到等效的 Unicode 字符(例如,html5['gt;'] == '>'),已被添加到 html.entities 模块。 该字典现在也被 HTMLParser 使用。(由 Ezio Melotti 在 bpo-11113bpo-15156 中贡献。)

imaplib

IMAP4_SSL 构造函数现在接受 SSLContext 参数以控制安全通道的参数。

(由 Sijin Joseph 在 bpo-8808 中贡献。)

inspect

添加了一个新的 getclosurevars() 函数。 此函数报告从函数体引用的所有名称的当前绑定,以及这些名称的解析位置,从而更容易在测试依赖于有状态闭包的代码时验证正确的内部状态。

(由 Meador Inge 和 Nick Coghlan 在 bpo-13062 中贡献。)

添加了一个新的 getgeneratorlocals() 函数。 此函数报告生成器堆栈帧中局部变量的当前绑定,从而更容易在测试生成器时验证正确的内部状态。

(由 Meador Inge 在 bpo-15153 中贡献。)

io

open() 函数有一个新的 'x' 模式,可用于独占地创建新文件,如果该文件已存在,则会引发 FileExistsError。 它基于 C11 的 fopen() ‘x’ 模式。

(由 David Townshend 在 bpo-12760 中贡献。)

TextIOWrapper 类的构造函数有一个新的可选参数 write_through。 如果 write_throughTrue,则保证对 write() 的调用不会被缓冲:写入 TextIOWrapper 对象的任何数据都会立即处理到其底层二进制缓冲区。

itertools

accumulate() 现在接受可选的 func 参数,用于提供用户提供的二元函数。

logging

basicConfig() 函数现在支持一个可选的 handlers 参数,该参数接受要添加到根记录器的处理程序的迭代。

已向 SysLogHandler 添加了一个类级别属性 append_nul,以允许控制将 NUL ( \000 ) 字节附加到系统日志记录,因为某些守护进程需要它,而另一些守护进程则将其传递到日志。

math

math 模块有一个新函数 log2(),它返回 x 的以 2 为底的对数。

(由 Mark Dickinson 在 bpo-11888 中编写。)

mmap

read() 方法现在与其他类似文件的对象更加兼容:如果省略了参数或指定为 None,它将返回从当前文件位置到映射末尾的字节。(由 Petri Lehtinen 在 bpo-12021 中贡献。)

multiprocessing

新的 multiprocessing.connection.wait() 函数允许使用超时轮询多个对象(例如连接、套接字和管道)。(由 Richard Oudkerk 在 bpo-12328 中贡献。)

multiprocessing.Connection 对象现在可以在多处理连接上传输。(由 Richard Oudkerk 在 bpo-4892 中贡献。)

multiprocessing.Process 现在接受一个 daemon 关键字参数,以覆盖从父进程继承 daemon 标志的默认行为 (bpo-6064)。

新属性 multiprocessing.Process.sentinel 允许程序使用适当的操作系统原语一次等待多个 Process 对象(例如,在 posix 系统上使用 select)。

新的方法 multiprocessing.pool.Pool.starmap()starmap_async() 提供了与现有 multiprocessing.pool.Pool.map()map_async() 函数等效的 itertools.starmap() 功能。(由 Hynek Schlawack 在 bpo-12708 中贡献。)

nntplib

nntplib.NNTP 类现在支持上下文管理协议,以便无条件地捕获 socket.error 异常并在完成后关闭 NNTP 连接

>>> from nntplib import NNTP
>>> with NNTP('news.gmane.org') as n:
...     n.group('gmane.comp.python.committers')
...
('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers')
>>>

(由 Giampaolo Rodolà 在 bpo-9795 中贡献。)

os

  • os 模块有一个新的 pipe2() 函数,它允许创建一个带有原子设置 O_CLOEXECO_NONBLOCK 标志的管道。这对于避免多线程程序中的竞争条件尤其有用。

  • os 模块有一个新的 sendfile() 函数,它提供了一种高效的“零拷贝”方式,用于将数据从一个文件(或套接字)描述符复制到另一个文件(或套接字)描述符。“零拷贝”是指两个描述符之间的数据复制完全由内核完成,而无需将数据复制到用户空间缓冲区。“零拷贝”是指两个描述符之间的数据复制完全由内核完成,而无需将数据复制到用户空间缓冲区。sendfile() 可用于高效地将数据从磁盘上的文件复制到网络套接字,例如用于下载文件。

    (由 Ross Lagerwall 和 Giampaolo Rodolà 在 bpo-10882 中提交。)

  • 为了避免像符号链接攻击以及临时文件和目录问题这样的竞争条件,操作文件描述符而不是文件名更可靠(也更快)。Python 3.3 增强了现有函数并引入了新的函数来处理文件描述符(bpo-4761, bpo-10755bpo-14626)。

  • access() 接受一个 effective_ids 关键字参数,以启用在访问检查中使用有效的 uid/gid 而不是真实的 uid/gid。可以通过 supports_effective_ids 集合检查此平台的平台支持情况。

  • os 模块有两个新函数:getpriority()setpriority()。它们可以用来获取或设置进程的 nice 值/优先级,方式类似于 os.nice(),但扩展到所有进程,而不仅仅是当前进程。

    (由 Giampaolo Rodolà 在 bpo-10784 中提交。)

  • 新的 os.replace() 函数允许跨平台重命名文件并覆盖目标文件。 使用 os.rename(),现有目标文件在 POSIX 下会被覆盖,但在 Windows 下会引发错误。(由 Antoine Pitrou 在 bpo-8828 中贡献。)

  • 现在,stat 函数族(stat(), fstat()lstat())支持以纳秒精度读取文件的时间戳。 对称地,utime() 现在可以以纳秒精度写入文件的时间戳。(由 Larry Hastings 在 bpo-14127 中贡献。)

  • 新的 os.get_terminal_size() 函数查询附加到文件描述符的终端的大小。另请参阅 shutil.get_terminal_size()。(由 Zbigniew Jędrzejewski-Szmek 在 bpo-13609 中贡献。)

pdb

现在不仅命令名称可以使用 Tab 补全,它们的参数也可以使用。 例如,对于 break 命令,函数和文件名都可以补全。

(由 Georg Brandl 在 bpo-14210 中贡献)

pickle

pickle.Pickler 对象现在有一个可选的 dispatch_table 属性,允许设置每个 pickler 的规约函数。

(由 Richard Oudkerk 在 bpo-14166 中贡献。)

pydoc

Tk GUI 和 serve() 函数已从 pydoc 模块中移除:pydoc -gserve() 在 Python 3.2 中已被弃用。

re

str 正则表达式现在支持 \u\U 转义。

(由 Serhiy Storchaka 在 bpo-3665 中贡献。)

sched

  • run() 现在接受一个 blocking 参数,当设置为 false 时,该方法将执行即将到期的已调度事件(如果有),然后立即返回。这在您希望在非阻塞应用程序中使用 scheduler 的情况下非常有用。(由 Giampaolo Rodolà 在 bpo-13449 中贡献。)

  • scheduler 类现在可以在多线程环境中安全使用。(由 Josiah Carlson 和 Giampaolo Rodolà 在 bpo-8684 中贡献。)

  • scheduler 类构造函数的 timefuncdelayfunct 参数现在是可选的,默认值分别为 time.time()time.sleep()。(由 Chris Clark 在 bpo-13245 中贡献。)

  • enter()enterabs()argument 参数现在是可选的。(由 Chris Clark 在 bpo-13245 中贡献。)

  • enter()enterabs() 现在接受一个 kwargs 参数。(由 Chris Clark 在 bpo-13245 中贡献。)

select

Solaris 及其衍生平台有一个新的类 select.devpoll,用于通过 /dev/poll 实现高性能异步套接字。(由 Jesús Cea Avión 在 bpo-6397 中贡献。)

shlex

之前未记录的辅助函数 quotepipes 模块移动到了 shlex 模块并被记录。quote() 正确转义了字符串中所有可能被 shell 赋予特殊含义的字符。

shutil

  • 新函数

    • disk_usage(): 提供总磁盘空间、已用磁盘空间和可用磁盘空间统计信息。(由 Giampaolo Rodolà 在 bpo-12442 中贡献。)

    • chown(): 允许更改给定路径的用户和/或组,也可以指定用户/组名称,而不仅仅是其数字 ID。(由 Sandro Tosi 在 bpo-12191 中贡献。)

    • shutil.get_terminal_size(): 返回解释器所连接的终端窗口的大小。(由 Zbigniew Jędrzejewski-Szmek 在 bpo-13609 中贡献。)

  • copy2()copystat() 现在在支持的平台上保留纳秒级精度的文件时间戳。它们还在 Linux 上保留文件“扩展属性”。(由 Larry Hastings 在 bpo-14127bpo-15238 中贡献。)

  • 现在有几个函数接受可选的 symlinks 参数:当该参数为 true 时,符号链接不会被解引用,而是对符号链接本身执行操作(或者如果相关,则创建一个符号链接)。(由 Hynek Schlawack 在 bpo-12715 中贡献。)

  • 当将文件复制到不同的文件系统时,move() 现在以 posix mv 命令的方式处理符号链接,重新创建符号链接而不是复制目标文件内容。(由 Jonathan Niehof 在 bpo-9993 中贡献。) move() 现在还返回 dst 参数作为其结果。

  • rmtree() 现在可以抵抗支持 os.open()os.unlink() 中新的 dir_fd 参数的平台上的符号链接攻击。(由 Martin von Löwis 和 Hynek Schlawack 在 bpo-4489 中贡献。)

signal

smtpd

smtpd 模块现在支持 RFC 5321(扩展 SMTP)和 RFC 1870(大小扩展)。根据标准,只有当客户端使用 EHLO 命令启动会话时,这些扩展才会被启用。

(最初的 ELHO 支持由 Alberto Trevino 提供。大小扩展由 Juhana Jauhiainen 提供。该补丁的大量额外工作由 Michele Orrù 和 Dan Boswell 贡献。bpo-8739

smtplib

现在,SMTPSMTP_SSLLMTP 类接受一个 source_address 关键字参数,用于指定在创建传出套接字时,绑定调用中用作源地址的 (主机, 端口)。(由 Paulo Scardine 在 bpo-11281 中贡献。)

SMTP 现在支持上下文管理协议,允许在 with 语句中使用 SMTP 实例。(由 Giampaolo Rodolà 在 bpo-11289 中贡献。)

SMTP_SSL 构造函数和 starttls() 方法现在接受一个 SSLContext 参数,用于控制安全通道的参数。(由 Kasun Herath 在 bpo-8809 中贡献。)

socket

socketserver

BaseServer 现在有一个可重写的方法 service_actions(),该方法由服务循环中的 serve_forever() 方法调用。ForkingMixIn 现在使用此方法来清理僵尸子进程。(由 Justin Warkentin 在 bpo-11109 中贡献。)

sqlite3

新的 sqlite3.Connection 方法 set_trace_callback() 可用于捕获 sqlite 处理的所有 sql 命令的跟踪。(由 Torsten Landschoff 在 bpo-11688 中贡献。)

ssl

  • ssl 模块有两个新的随机生成函数

    • RAND_bytes():生成加密强度高的伪随机字节。

    • RAND_pseudo_bytes():生成伪随机字节。

    (由 Victor Stinner 在 bpo-12049 中贡献。)

  • ssl 模块现在公开了更细粒度的异常层次结构,以便更容易检查各种类型的错误。(由 Antoine Pitrou 在 bpo-11183 中贡献。)

  • load_cert_chain() 现在接受一个 password 参数,如果私钥被加密,则使用该参数。(由 Adam Simpkins 在 bpo-12803 中贡献。)

  • 现在通过 load_dh_params()set_ecdh_curve() 方法支持常规的 Diffie-Hellman 密钥交换和基于椭圆曲线的密钥交换。(由 Antoine Pitrou 在 bpo-13626bpo-13627 中贡献。)

  • SSL 套接字有一个新的 get_channel_binding() 方法,允许实现某些身份验证机制,例如 SCRAM-SHA-1-PLUS。(由 Jacek Konieczny 在 bpo-12551 中贡献。)

  • 您可以查询 SSL 套接字使用的 SSL 压缩算法,这要归功于其新的 compression() 方法。新的属性 OP_NO_COMPRESSION 可用于禁用压缩。(由 Antoine Pitrou 在 bpo-13634 中贡献。)

  • 已使用 ssl.SSLContext.set_npn_protocols() 方法添加了对下一协议协商扩展的支持。(由 Colin Marc 在 bpo-14204 中贡献。)

  • 现在,由于 libraryreason 属性,可以更轻松地内省 SSL 错误。(由 Antoine Pitrou 在 bpo-14837 中贡献。)

  • get_server_certificate() 函数现在支持 IPv6。(由 Charles-François Natali 在 bpo-11811 中贡献。)

  • 新的属性 OP_CIPHER_SERVER_PREFERENCE 允许设置 SSLv3 服务器套接字以使用服务器的密码排序首选项,而不是客户端的首选项 (bpo-13635)。

stat

未文档化的 tarfile.filemode 函数已移至 stat.filemode()。它可用于将文件的模式转换为 ‘-rwxrwxrwx’ 形式的字符串。

(由 Giampaolo Rodolà 在 bpo-14807 中贡献。)

struct

struct 模块现在通过新的代码 nN 分别支持 ssize_tsize_t。(由 Antoine Pitrou 在 bpo-3163 中贡献。)

subprocess

现在,在 posix 平台上,命令字符串可以是字节对象。(由 Victor Stinner 在 bpo-8513 中贡献。)

新的常量 DEVNULL 允许以平台无关的方式抑制输出。(由 Ross Lagerwall 在 bpo-5870 中贡献。)

sys

sys 模块有一个新的 thread_info 命名元组,其中包含有关线程实现的信息 (bpo-11223)。

tarfile

tarfile 现在通过 lzma 模块支持 lzma 编码。(由 Lars Gustäbel 在 bpo-5689 中贡献。)

tempfile

tempfile.SpooledTemporaryFiletruncate() 方法现在接受一个 size 参数。(由 Ryan Kelly 在 bpo-9957 中贡献。)

textwrap

textwrap 模块有一个新的 indent() 方法,可以轻松地在文本块中的选定行添加通用前缀 (bpo-13857)。

threading

threading.Conditionthreading.Semaphorethreading.BoundedSemaphorethreading.Eventthreading.Timer,这些以前都是返回类实例的工厂函数,现在都是类,可以被继承。(由 Éric Araujo 在 bpo-10968 中贡献。)

threading.Thread 构造函数现在接受一个 daemon 关键字参数,以覆盖从父线程继承 daemon 标志值的默认行为 (bpo-6064)。

以前的私有函数 _thread.get_ident 现在作为公共函数 threading.get_ident() 可用。这消除了 stdlib 中对 _thread 模块的直接访问的几种情况。使用 _thread.get_ident 的第三方代码也应该改为使用新的公共接口。

time

PEP 418time 模块添加了新函数

  • get_clock_info():获取有关时钟的信息。

  • monotonic():单调时钟(不能后退),不受系统时钟更新的影响。

  • perf_counter():具有最高可用分辨率的性能计数器,用于测量短时间间隔。

  • process_time():当前进程的系统和用户 CPU 时间之和。

其他新函数

为了提高跨平台的一致性,当传递负的睡眠值时,sleep() 现在会引发 ValueError。以前这在 posix 上是一个错误,但在 Windows 上会产生无限睡眠。

types

添加一个新的 types.MappingProxyType 类:映射的只读代理。( bpo-14386)

新的函数 types.new_class()types.prepare_class() 为符合 PEP 3115 的动态类型创建提供支持。( bpo-14588)

unittest

assertRaises()assertRaisesRegex()assertWarns()assertWarnsRegex() 现在在用作上下文管理器时接受关键字参数 msg。(由 Ezio Melotti 和 Winston Ewert 在 bpo-10775 中贡献。)

unittest.TestCase.run() 现在返回 TestResult 对象。

urllib

Request 类现在接受一个 method 参数,该参数由 get_method() 用于确定应使用哪个 HTTP 方法。例如,这将发送一个 'HEAD' 请求

>>> urlopen(Request('https://pythonlang.cn', method='HEAD'))

(bpo-1673007)

webbrowser

webbrowser 模块支持更多“浏览器”:Google Chrome(命名为 chromechromiumchrome-browserchromium-browser,具体取决于版本和操作系统)以及来自 FreeDesktop.org 项目的通用启动器 xdg-open 和 GNOME 3 的默认 URI 处理程序 gvfs-open。(前者由 Arnaud Calmettes 在 bpo-13620 中贡献,后者由 Matthias Klose 在 bpo-14493 中贡献。)

xml.etree.ElementTree

现在,xml.etree.ElementTree 模块默认导入其 C 加速器;不再需要显式导入 xml.etree.cElementTree (此模块为了向后兼容而保留,但现在已被弃用)。 此外,Elementiter 方法系列已得到优化 (用 C 重写)。该模块的文档也得到了极大的改进,增加了示例和更详细的参考。

zlib

新的属性 zlib.Decompress.eof 可以区分格式正确的压缩流和不完整或截断的压缩流。(由 Nadeem Vawda 在 bpo-12646 中贡献。)

新的属性 zlib.ZLIB_RUNTIME_VERSION 报告运行时加载的底层 zlib 库的版本字符串。(由 Torsten Landschoff 在 bpo-12306 中贡献。)

优化

添加了主要的性能增强功能

  • 感谢 PEP 393,对 Unicode 字符串的一些操作进行了优化

    • 内存占用量根据文本的不同减少了 2 到 4 倍

    • 将 ASCII 字符串编码为 UTF-8 时不再需要编码字符,UTF-8 表示形式与 ASCII 表示形式共享

    • UTF-8 编码器已得到优化

    • 重复单个 ASCII 字母并获取 ASCII 字符串的子字符串的速度提高了 4 倍

  • UTF-8 现在速度提高了 2 到 4 倍。UTF-16 编码现在速度提高了 10 倍。

    (由 Serhiy Storchaka 贡献,bpo-14624bpo-14738bpo-15026。)

构建和 C API 更改

对 Python 的构建过程和 C API 的更改包括

已弃用

不支持的操作系统

由于缺少维护者,不再支持 OS/2 和 VMS。

由于维护负担,不再支持 Windows 2000 和将 COMSPEC 设置为 command.com 的 Windows 平台。

在 3.2 中已弃用的 OSF 支持已完全删除。

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

C API 中已弃用的函数和类型

Py_UNICODE 已被 PEP 393 弃用,并将在 Python 4 中移除。所有使用此类型的函数都被弃用。

使用 Py_UNICODEPy_UNICODE* 类型的 Unicode 函数和方法

操作 Py_UNICODE* 字符串的函数和宏

编码器

已弃用的特性

array 模块的 'u' 格式代码现在已被弃用,并将在 Python 4 中与其余的 (Py_UNICODE) API 一起移除。

移植到 Python 3.3

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

移植 Python 代码

  • 哈希随机化默认启用。将 PYTHONHASHSEED 环境变量设置为 0 以禁用哈希随机化。另请参阅 object.__hash__() 方法。

  • bpo-12326: 在 Linux 上,sys.platform 不再包含主版本号。它现在始终为 ‘linux’,而不是根据用于构建 Python 的 Linux 版本而定的 ‘linux2’ 或 ‘linux3’。将 sys.platform == ‘linux2’ 替换为 sys.platform.startswith(‘linux’),或者如果您不需要支持较旧的 Python 版本,则直接替换为 sys.platform == ‘linux’。

  • bpo-13847, bpo-14180: timedatetime: 如果时间戳超出范围,现在会引发 OverflowError 错误,而不是 ValueError 错误。如果 C 函数 gmtime()localtime() 失败,现在会引发 OSError 错误。

  • import 使用的默认查找器现在会缓存特定目录中包含的内容。如果您创建了 Python 源代码文件或无源代码的字节码文件,请务必调用 importlib.invalidate_caches() 来清除查找器的缓存,以便查找器能够注意到新文件。

  • ImportError 现在使用尝试导入的模块的完整名称。检查 ImportErrors 消息的 doctest 需要更新为使用模块的完整名称,而不仅仅是名称的尾部。

  • __import__() 的 *index* 参数现在默认为 0 而不是 -1,并且不再支持负值。在实现 PEP 328 时,默认值仍然为 -1 是一个疏忽。如果您需要继续执行相对导入,然后再执行绝对导入,则可以使用索引 1 执行相对导入,然后使用索引 0 执行另一次导入。不过,建议您使用 importlib.import_module(),而不是直接调用 __import__()

  • __import__() 不再允许对顶级模块使用除 0 以外的索引值。例如,__import__('sys', level=1) 现在会报错。

  • 由于 sys.meta_pathsys.path_hooks 默认情况下现在都有查找器,您很可能需要使用 list.insert() 而不是 list.append() 来添加到这些列表中。

  • 由于 None 现在被插入到 sys.path_importer_cache 中,如果您要清除字典中没有查找器的路径条目,则需要删除与 None **和** imp.NullImporter 值配对的键,以实现向后兼容。这将导致在旧版本的 Python 上产生额外的开销,这些旧版本的 Python 会将 None 重新插入到 sys.path_importer_cache 中,其中它表示隐式查找器的使用,但从语义上讲,它不应该改变任何内容。

  • importlib.abc.Finder 不再指定必须实现的 find_module() 抽象方法。如果您依赖子类来实现该方法,请确保首先检查该方法是否存在。不过,您可能需要首先检查 find_loader(),以便在使用 路径条目查找器 时正常工作。

  • pkgutil 已转换为在内部使用 importlib。这消除了许多边缘情况,在这些情况下,旧的 PEP 302 导入模拟未能匹配实际导入系统的行为。导入模拟本身仍然存在,但现在已弃用。pkgutil.iter_importers()pkgutil.walk_packages() 函数特殊处理标准导入钩子,因此即使它们不提供非标准的 iter_modules() 方法,它们仍然受支持。

  • email.header.decode_header() 所做的解析中存在一个长期的 RFC 合规性错误 (bpo-1079) 已修复。使用标准习惯用法将编码的标头转换为 unicode 的代码(str(make_header(decode_header(h)))将看不到任何变化,但是查看 decode_header 返回的各个元组的代码会发现,位于 ASCII 部分之前或之后的空格现在包含在 ASCII 部分中。使用 make_header 构建标头的代码也应该继续正常工作,因为如果输入字符串中尚不存在,make_header 会继续在 ASCII 和非 ASCII 部分之间添加空格。

  • email.utils.formataddr() 现在在传递非 ASCII 显示名称时会执行正确的内容传输编码。任何依赖先前错误行为(在格式化输出字符串中保留非 ASCII unicode)的代码都需要更改 (bpo-1690608)。

  • poplib.POP3.quit() 现在可能会像所有其他 poplib 方法一样引发协议错误。如果特定应用程序遇到 quit 上的错误,则假设 quit 不会引发 poplib.error_proto 错误的代码可能需要更改 (bpo-11291)。

  • 自 Python 2.4 起已弃用的 email.parser.Parserstrict 参数已最终删除。

  • 已删除已弃用的方法 unittest.TestCase.assertSameElements

  • 已删除已弃用的变量 time.accept2dyear

  • 已从 decimal 模块中删除已弃用的 Context._clamp 属性。它之前已被公共属性 clamp 替换。(请参阅 bpo-8540。)

  • 已从 smtplib 中删除未记录的内部辅助类 SSLFakeFile,因为它的功能早已由 socket.socket.makefile() 直接提供。

  • 现在,在 Windows 上向 time.sleep() 传递负值会引发错误,而不是永远休眠。它在 posix 上始终会引发错误。

  • 已删除 ast.__version__ 常量。如果您需要做出受 AST 版本影响的决策,请使用 sys.version_info 来做出决策。

  • 通过子类化私有类来解决 threading 模块使用工厂函数的事实的代码,将需要更改为子类化现在是公共的类。

  • 线程模块中未记录的调试机制已删除,从而简化了代码。这应该对生产代码没有影响,但此处提及是为了以防任何应用程序调试框架与之交互 (bpo-13550)。

移植 C 代码

  • 在对缓冲区 API 进行更改的过程中,已删除未记录的 Py_buffer 结构的 smalltable 成员,并且 PyMemoryViewObject 的布局已更改。

    所有依赖于 memoryobject.hobject.h 中相关部分的扩展都必须重新构建。

  • 由于 PEP 393Py_UNICODE 类型以及所有使用该类型的函数已被弃用(但至少会保留五年)。如果您之前使用底层 Unicode API 来构造和访问 Unicode 对象,并且希望利用 PEP 393 提供的内存占用减少的优势,您必须将代码转换为新的 Unicode API

    但是,如果您只使用诸如 PyUnicode_Concat()PyUnicode_Join()PyUnicode_FromFormat() 之类的高级函数,您的代码将自动利用新的 Unicode 表示形式。

  • PyImport_GetMagicNumber() 现在在失败时返回 -1

  • 由于 __import__()level 参数的负值不再有效,因此 PyImport_ImportModuleLevel() 也同样如此。这也意味着 PyImport_ImportModuleEx() 使用的 level 值现在是 0 而不是 -1

构建 C 扩展

  • C 扩展的可能文件名范围已缩小。已取消使用很少使用的拼写:在 POSIX 下,名为 xxxmodule.soxxxmodule.abi3.soxxxmodule.cpython-*.so 的文件不再被识别为实现 xxx 模块。如果您之前生成过此类文件,则必须切换到其他拼写(即,从文件名中删除 module 字符串)。

    (在 bpo-14040 中实现。)

命令行开关更改

  • -Q 命令行标志和相关工件已被删除。检查 sys.flags.division_warning 的代码需要更新。

    bpo-10998,由 Éric Araujo 贡献。)

  • 当使用 -S 启动 python 时,import site 将不再向模块搜索路径添加特定于站点的路径。在以前的版本中,它是这样做的。

    bpo-11591,由 Carl Meyer 贡献,并由 Éric Araujo 编辑。)