Python 3.3 的新特性¶
本文介绍了 Python 3.3 相对于 3.2 的新特性。Python 3.3 于 2012 年 9 月 29 日发布。有关完整详细信息,请参阅变更日志。
另请参阅
PEP 398 - Python 3.3 发布时间表
摘要 – 发布亮点¶
新的语法特性
新的库模块
faulthandler
(有助于调试底层崩溃)ipaddress
(表示 IP 地址和掩码的高级对象)lzma
(使用 XZ / LZMA 算法压缩数据)unittest.mock
(用模拟对象替换被测系统的一部分)
新的内置特性
重构的 I/O 异常层次结构。
实现改进
更紧凑的 unicode 字符串。
更紧凑的 属性字典。
显著改进的库模块
安全改进
默认情况下启用哈希随机化。
请继续阅读以获取面向用户的更改的完整列表。
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+0000
到U+10FFFF
)。窄版本和宽版本之间的区别不再存在,Python 现在的行为类似于宽版本,即使在 Windows 下也是如此。随着窄版本的消亡,特定于窄版本的问题也已得到修复,例如
len()
现在对于非 BMP 字符始终返回 1,因此len('\U0010FFFF') == 1
;代理对不会在字符串字面量中重新组合,因此
'\uDBFF\uDFFF' != '\U0010FFFF'
;索引或切片非 BMP 字符会返回期望的值,因此
'\U0010FFFF'[0]
现在返回'\U0010FFFF'
,而不是'\uDBFF'
;标准库中的所有其他函数现在都可以正确处理非 BMP 代码点。
sys.maxunicode
的值现在始终为1114111
(十六进制为0x10FFFF
)。为了向后兼容,PyUnicode_GetMax()
函数仍然返回0xFFFF
或0x10FFFF
,并且不应将其与新的 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 异常层次结构¶
现在,由操作系统错误引发的异常层次结构既简化又更加精细。
您不必再担心在 OSError
、IOError
、EnvironmentError
、WindowsError
、mmap.error
、socket.error
或 select.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]
推动此更改的主要原则是,即使是那些设计为与 send
和 throw
方法一起使用的生成器,也可以像将一个大型函数拆分成多个子函数一样轻松地拆分成多个子生成器。
另请参阅
- 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.Signature
、inspect.Parameter
和 inspect.BoundArguments
保存有关调用签名的信息,例如,注解、默认值、参数类型和绑定参数,这大大简化了编写装饰器以及任何验证或修改调用签名或参数的代码。
另请参阅
- PEP 362: - 函数签名对象
PEP 由 Brett Cannon、Yury Selivanov、Larry Hastings、Jiwon Seo 撰写;由 Yury Selivanov 实现。
PEP 421:添加 sys.implementation¶
sys
模块上的一个新属性公开了当前正在运行的解释器实现的特定细节。sys.implementation
上的初始属性集为 name
、version
、hexversion
和 cache_tag
。
sys.implementation
的目的是将标准库使用的特定于实现的数据整合到一个命名空间中。这使得不同的 Python 实现可以更容易地共享单个标准库代码库。在其初始状态下,sys.implementation
仅保留一小部分特定于实现的数据。随着时间的推移,该比例将发生变化,以使标准库更具可移植性。
改进标准库可移植性的一个例子是 cache_tag
。从 Python 3.3 开始,sys.implementation.cache_tag
被 importlib
用来支持 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.MetaPathFinder
和 importlib.abc.PathEntryFinder
,来正确区分 元路径查找器 和 路径条目查找器。旧的 importlib.abc.Finder
抽象基类现在仅为了向后兼容性而提供,并且不强制任何方法要求。
就查找器而言,importlib.machinery.FileFinder
公开了用于搜索模块的源文件和字节码文件的机制。以前,此类是 sys.path_hooks
的隐式成员。
对于加载器,新的抽象基类 importlib.abc.FileLoader
有助于编写一个使用文件系统作为模块代码存储机制的加载器。现在可以直接使用源文件的加载器 (importlib.machinery.SourceFileLoader
)、无源字节码文件的加载器 (importlib.machinery.SourcelessFileLoader
) 和扩展模块的加载器 (importlib.machinery.ExtensionFileLoader
)。
现在,ImportError
具有 name
和 path
属性,当有相关数据提供时会设置这些属性。现在,导入失败的消息还将提供模块的完整名称,而不仅仅是模块名称的末尾部分。
现在,importlib.invalidate_caches()
函数将调用缓存在 sys.path_importer_cache
中的所有查找器上的同名方法,以帮助清理任何必要的存储状态。
可见的更改¶
有关代码的潜在所需更改,请参阅 移植 Python 代码 部分。
除了 importlib
现在公开的内容之外,导入还有其他可见的更改。最大的变化是 sys.meta_path
和 sys.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)现在,
bytes
和bytearray
对象的count()
、find()
、rfind()
、index()
和rindex()
方法接受一个介于 0 和 255 之间的整数作为它们的第一个参数。(由 Petri Lehtinen 在 bpo-12170 中贡献。)
现在,
bytes
和bytearray
对象的rjust()
、ljust()
和center()
方法接受一个bytearray
作为fill
参数。(由 Petri Lehtinen 在 bpo-12380 中贡献。)新的方法已添加到
list
和bytearray
:copy()
和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()
以安装 SIGSEGV
、SIGFPE
、SIGABRT
、SIGBUS
和 SIGILL
信号的故障处理程序。您还可以通过设置 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__
作为动态更新的属性提供。内置描述符已相应更新。
abc.abstractproperty
已弃用,请改用带有abc.abstractmethod()
的property
。abc.abstractclassmethod
已弃用,请改用带有abc.abstractmethod()
的classmethod
。abc.abstractstaticmethod
已弃用,请改用带有abc.abstractmethod()
的staticmethod
。
(由 Darren Dale 在 bpo-11610 中贡献。)
abc.ABCMeta.register()
现在返回已注册的子类,这意味着它现在可以用作类装饰器 (bpo-10868)。
array¶
array
模块使用 q
和 Q
类型代码支持 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.BZ2File
和bz2.decompress()
现在可以解压缩多流输入(例如,由 pbzip2 工具生成的输入)。bz2.BZ2File
现在也可以使用'a'
(追加)模式来创建这种类型的文件。(由 Nir Aides 在 bpo-1625 中贡献。)
bz2.BZ2File
现在实现了所有io.BufferedIOBase
API,除了detach()
和truncate()
方法。
codecs¶
mbcs
编解码器已被重写,以便在所有 Windows 版本上正确处理 replace
和 ignore
错误处理程序。mbcs
编解码器现在支持所有错误处理程序,而不仅仅是 replace
进行编码和 ignore
进行解码。
添加了一个新的仅限 Windows 的编解码器:cp65001
(bpo-13216)。它是 Windows 代码页 65001(Windows UTF-8,CP_UTF8
)。例如,如果控制台输出代码页设置为 cp65001(例如,使用 chcp 65001
命令),则 sys.stdout
会使用它。
多字节 CJK 解码器现在可以更快地重新同步。它们只会忽略无效字节序列的第一个字节。例如,b'\xff\n'.decode('gb2312', 'replace')
现在会在替换字符后返回一个 \n
。
增量 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.'
。
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
模块的同步对象)中获取其资源。
crypt¶
向 crypt
模块添加 salt 和模块化 crypt 格式(哈希方法)以及 mksalt()
函数。
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¶
天真型和感知型
datetime
实例之间的相等比较现在返回False
,而不是引发TypeError
(bpo-15006)。新的
datetime.datetime.timestamp()
方法:返回与datetime
实例对应的 POSIX 时间戳。datetime.datetime.strftime()
方法支持格式化早于 1000 年的年份。datetime.datetime.astimezone()
方法现在可以在不带参数的情况下调用,以将 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
在上下文模板(
DefaultContext
、BasicContext
和ExtendedContext
)中,Emax
和Emin
的幅度已更改为999999
。decimal.py 中的
Decimal
构造函数不遵守上下文限制,并精确转换具有任意指数或精度的值。由于 C 版本具有内部限制,因此使用以下方案:如果可能,则精确转换值,否则引发InvalidOperation
异常,结果为 NaN。在后一种情况下,始终可以使用create_decimal()
以获得舍入或不精确的值。decimal.py 中的幂函数始终正确舍入。在 C 版本中,它根据正确舍入的
exp()
和ln()
函数定义,但最终结果仅“几乎始终正确舍入”。在 C 版本中,包含信号的上下文字典是
MutableMapping
。出于速度原因,flags
和traps
始终引用初始化上下文时使用的同一个MutableMapping
。如果分配了新的信号字典,flags
和traps
将使用新值更新,但它们不引用 RHS 字典。为了使 Python 和 C 版本具有通用的交换格式,对
Context
进行 pickle 操作会产生不同的输出。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 |
当序列化 |
linesep |
当序列化 |
cte_type |
|
raise_on_defect |
导致 |
使用策略对象的 clone()
方法创建具有新设置的新策略实例。clone
将上述任何控件作为关键字参数。调用中未指定的任何控件都保留其默认值。因此,您可以创建一个像这样使用 \r\n
行分隔符字符的策略
mypolicy = compat32.clone(linesep='\r\n')
可以使用策略来简化应用程序所需的格式的消息生成。无需记住在所有调用 generator
的地方指定 linesep='\r\n'
,您可以在设置 parser
或 Message
使用的策略时指定一次,无论您的程序使用哪个来创建 Message
对象。另一方面,如果您需要生成多种形式的消息,您仍然可以在相应的 generator
调用中指定参数。或者,您可以为不同的情况使用自定义策略实例,并在创建 generator
时传入这些实例。
带有新标头 API 的临时策略¶
尽管策略框架本身就很有价值,但引入它的主要动机是允许创建新的策略,以一种为不使用新策略的用户保持向后兼容性的方式,为电子邮件包实现新功能。由于新策略引入了新的 API,我们在 Python 3.3 中将其作为临时策略发布。如果核心开发人员认为有必要,可能会发生向后不兼容的更改(包括删除代码)。
新的策略是 EmailPolicy
的实例,并添加了以下附加控制:
refold_source |
控制由 |
header_factory |
一个可调用对象,它接受一个 |
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]>'
当你解析消息时,你可以使用标头对象的 addresses
和 groups
属性来访问组和单个地址
>>> 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。
新的实用函数
format_datetime()
:给定一个datetime
,生成一个格式化的字符串,用于电子邮件标头。parsedate_to_datetime()
:给定一个来自电子邮件标头的日期字符串,将其转换为一个感知时区的datetime
,如果偏移量为-0000
,则转换为一个朴素的datetime
。localtime()
:没有参数时,返回当前本地时间,作为使用本地timezone
的感知时区的datetime
。给定一个感知时区的datetime
,将其转换为使用本地timezone
的感知时区的datetime
。
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-15114 和 bpo-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-11113 和 bpo-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_through 为 True
,则保证对 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_CLOEXEC
或O_NONBLOCK
标志的管道。这对于避免多线程程序中的竞争条件尤其有用。os
模块有一个新的sendfile()
函数,它提供了一种高效的“零拷贝”方式,用于将数据从一个文件(或套接字)描述符复制到另一个文件(或套接字)描述符。“零拷贝”是指两个描述符之间的数据复制完全由内核完成,而无需将数据复制到用户空间缓冲区。“零拷贝”是指两个描述符之间的数据复制完全由内核完成,而无需将数据复制到用户空间缓冲区。sendfile()
可用于高效地将数据从磁盘上的文件复制到网络套接字,例如用于下载文件。(由 Ross Lagerwall 和 Giampaolo Rodolà 在 bpo-10882 中提交。)
为了避免像符号链接攻击以及临时文件和目录问题这样的竞争条件,操作文件描述符而不是文件名更可靠(也更快)。Python 3.3 增强了现有函数并引入了新的函数来处理文件描述符(bpo-4761, bpo-10755 和 bpo-14626)。
os
模块有一个新的fwalk()
函数,它类似于walk()
,但它也会产生引用访问目录的文件描述符。这对于避免符号链接竞争尤其有用。以下函数获取新的可选 dir_fd (相对于目录描述符的路径)和/或 follow_symlinks (不跟随符号链接):
access()
,chflags()
,chmod()
,chown()
,link()
,lstat()
,mkdir()
,mkfifo()
,mknod()
,open()
,readlink()
,remove()
,rename()
,replace()
,rmdir()
,stat()
,symlink()
,unlink()
,utime()
。可以通过集合os.supports_dir_fd
和os.supports_follows_symlinks
检查使用这些参数的平台支持情况。以下函数现在支持其路径参数的文件描述符:
chdir()
,chmod()
,chown()
,execve()
,listdir()
,pathconf()
,exists()
,stat()
,statvfs()
,utime()
。可以通过os.supports_fd
集合检查此平台的平台支持情况。
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 中贡献。)
支持 Linux 扩展属性的新函数 (bpo-12720):
getxattr()
、listxattr()
、removexattr()
、setxattr()
。调度器的新接口。 这些函数控制操作系统如何为进程分配 CPU 时间。 新函数:
sched_get_priority_max()
、sched_get_priority_min()
、sched_getaffinity()
、sched_getparam()
、sched_getscheduler()
、sched_rr_get_interval()
、sched_setaffinity()
、sched_setparam()
、sched_setscheduler()
、sched_yield()
。控制文件系统的新函数
posix_fadvise()
: 声明以特定模式访问数据的意图,从而允许内核进行优化。posix_fallocate()
: 确保为文件分配足够的磁盘空间。sync()
: 强制将所有内容写入磁盘。
其他新的 posix 函数
lockf()
: 在打开的文件描述符上应用、测试或移除 POSIX 锁。pread()
: 从文件描述符的偏移量处读取,文件偏移量保持不变。pwrite()
: 从偏移量处写入文件描述符,文件偏移量保持不变。readv()
: 从文件描述符读取到多个可写缓冲区中。truncate()
: 截断与 *path* 对应的文件,使其大小至多为 *length* 个字节。waitid()
: 等待一个或多个子进程完成。writev()
: 将 *buffers* 的内容写入文件描述符,其中 *buffers* 是任意的缓冲区序列。getgrouplist()
(bpo-9344): 返回指定用户所属的组 ID 列表。
某些平台现在支持
lseek()
函数的其他常量,例如os.SEEK_HOLE
和os.SEEK_DATA
。新常量
RTLD_LAZY
、RTLD_NOW
、RTLD_GLOBAL
、RTLD_LOCAL
、RTLD_NODELETE
、RTLD_NOLOAD
和RTLD_DEEPBIND
在支持它们的平台上可用。 这些用于sys.setdlopenflags()
函数,并取代了ctypes
和DLFCN
中定义的类似常量。(由 Victor Stinner 在 bpo-13226 中贡献。)为了简化跨平台支持,
os.symlink()
现在在非 Windows 平台上接受(并忽略)target_is_directory
关键字参数。
pdb¶
现在不仅命令名称可以使用 Tab 补全,它们的参数也可以使用。 例如,对于 break
命令,函数和文件名都可以补全。
(由 Georg Brandl 在 bpo-14210 中贡献)
pickle¶
pickle.Pickler
对象现在有一个可选的 dispatch_table
属性,允许设置每个 pickler 的规约函数。
(由 Richard Oudkerk 在 bpo-14166 中贡献。)
pydoc¶
Tk GUI 和 serve()
函数已从 pydoc
模块中移除:pydoc -g
和 serve()
在 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
类构造函数的 timefunc 和 delayfunct 参数现在是可选的,默认值分别为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¶
之前未记录的辅助函数 quote
从 pipes
模块移动到了 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-14127 和 bpo-15238 中贡献。)现在有几个函数接受可选的
symlinks
参数:当该参数为 true 时,符号链接不会被解引用,而是对符号链接本身执行操作(或者如果相关,则创建一个符号链接)。(由 Hynek Schlawack 在 bpo-12715 中贡献。)当将文件复制到不同的文件系统时,
move()
现在以 posixmv
命令的方式处理符号链接,重新创建符号链接而不是复制目标文件内容。(由 Jonathan Niehof 在 bpo-9993 中贡献。)move()
现在还返回dst
参数作为其结果。rmtree()
现在可以抵抗支持os.open()
和os.unlink()
中新的dir_fd
参数的平台上的符号链接攻击。(由 Martin von Löwis 和 Hynek Schlawack 在 bpo-4489 中贡献。)
signal¶
signal
模块有新的函数pthread_sigmask()
: 获取和/或更改调用线程的信号掩码(由 Jean-Paul Calderone 在 bpo-8407 中贡献);pthread_kill()
: 向线程发送信号;sigpending()
: 检查待处理的函数;sigwait()
: 等待信号;sigwaitinfo()
: 等待信号,返回关于信号的详细信息;sigtimedwait()
: 类似于sigwaitinfo()
,但有超时。
信号处理程序将信号编号作为单个字节写入唤醒文件描述符,而不是空字节。因此可以等待多个信号,并知道引发了哪些信号。
signal.signal()
和signal.siginterrupt()
引发 OSError,而不是 RuntimeError: OSError 有一个 errno 属性。
smtpd¶
smtpd
模块现在支持 RFC 5321(扩展 SMTP)和 RFC 1870(大小扩展)。根据标准,只有当客户端使用 EHLO
命令启动会话时,这些扩展才会被启用。
(最初的 ELHO
支持由 Alberto Trevino 提供。大小扩展由 Juhana Jauhiainen 提供。该补丁的大量额外工作由 Michele Orrù 和 Dan Boswell 贡献。bpo-8739)
smtplib¶
现在,SMTP
、SMTP_SSL
和 LMTP
类接受一个 source_address
关键字参数,用于指定在创建传出套接字时,绑定调用中用作源地址的 (主机, 端口)
。(由 Paulo Scardine 在 bpo-11281 中贡献。)
SMTP
现在支持上下文管理协议,允许在 with
语句中使用 SMTP
实例。(由 Giampaolo Rodolà 在 bpo-11289 中贡献。)
SMTP_SSL
构造函数和 starttls()
方法现在接受一个 SSLContext 参数,用于控制安全通道的参数。(由 Kasun Herath 在 bpo-8809 中贡献。)
socket¶
当底层平台支持时,
socket
类现在公开了额外的处理辅助数据的方法(由 David Watson 在 bpo-6560 中贡献,基于 Heiko Wundram 之前的补丁)
socket
类现在支持 Linux 上的 PF_CAN 协议族 (https://en.wikipedia.org/wiki/Socketcan, https://lwn.net/Articles/253425)。(由 Matthias Fuchs 贡献,Tiago Gonçalves 在 bpo-10141 中更新。)
socket
类现在支持 PF_RDS 协议族 (https://en.wikipedia.org/wiki/Reliable_Datagram_Sockets 和 https://oss.oracle.com/projects/rds)。socket
类现在支持 OS X 上的PF_SYSTEM
协议族。(由 Michael Goderbauer 在 bpo-13777 中贡献。)新的函数
sethostname()
允许在 Unix 系统上设置主机名,如果调用进程具有足够的权限。(由 Ross Lagerwall 在 bpo-10866 中贡献。)
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-13626 和 bpo-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 中贡献。)现在,由于
library
和reason
属性,可以更轻松地内省 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
模块现在通过新的代码 n
和 N
分别支持 ssize_t
和 size_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.SpooledTemporaryFile
的 truncate()
方法现在接受一个 size
参数。(由 Ryan Kelly 在 bpo-9957 中贡献。)
textwrap¶
textwrap
模块有一个新的 indent()
方法,可以轻松地在文本块中的选定行添加通用前缀 (bpo-13857)。
threading¶
threading.Condition
、threading.Semaphore
、threading.BoundedSemaphore
、threading.Event
和 threading.Timer
,这些以前都是返回类实例的工厂函数,现在都是类,可以被继承。(由 Éric Araujo 在 bpo-10968 中贡献。)
threading.Thread
构造函数现在接受一个 daemon
关键字参数,以覆盖从父线程继承 daemon
标志值的默认行为 (bpo-6064)。
以前的私有函数 _thread.get_ident
现在作为公共函数 threading.get_ident()
可用。这消除了 stdlib 中对 _thread
模块的直接访问的几种情况。使用 _thread.get_ident
的第三方代码也应该改为使用新的公共接口。
time¶
get_clock_info()
:获取有关时钟的信息。monotonic()
:单调时钟(不能后退),不受系统时钟更新的影响。perf_counter()
:具有最高可用分辨率的性能计数器,用于测量短时间间隔。process_time()
:当前进程的系统和用户 CPU 时间之和。
其他新函数
带有
CLOCK_xxx
常量的clock_getres()
、clock_gettime()
和clock_settime()
函数。(由 Victor Stinner 在 bpo-10278 中贡献。)
为了提高跨平台的一致性,当传递负的睡眠值时,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'))
webbrowser¶
webbrowser
模块支持更多“浏览器”:Google Chrome(命名为 chrome、chromium、chrome-browser 或 chromium-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
(此模块为了向后兼容而保留,但现在已被弃用)。 此外,Element
的 iter
方法系列已得到优化 (用 C 重写)。该模块的文档也得到了极大的改进,增加了示例和更详细的参考。
zlib¶
新的属性 zlib.Decompress.eof
可以区分格式正确的压缩流和不完整或截断的压缩流。(由 Nadeem Vawda 在 bpo-12646 中贡献。)
新的属性 zlib.ZLIB_RUNTIME_VERSION
报告运行时加载的底层 zlib
库的版本字符串。(由 Torsten Landschoff 在 bpo-12306 中贡献。)
优化¶
添加了主要的性能增强功能
构建和 C API 更改¶
对 Python 的构建过程和 C API 的更改包括
新的 PEP 3118 相关函数
PEP 393 添加了新的 Unicode 类型、宏和函数
高级 API
低级 API
PyUnicode_DATA
,PyUnicode_1BYTE_DATA
,PyUnicode_2BYTE_DATA
,PyUnicode_4BYTE_DATA
PyUnicode_KIND
与PyUnicode_Kind
枚举:PyUnicode_WCHAR_KIND
,PyUnicode_1BYTE_KIND
,PyUnicode_2BYTE_KIND
,PyUnicode_4BYTE_KIND
PyArg_ParseTuple
现在接受bytearray
作为c
格式 (bpo-12380)。
已弃用¶
不支持的操作系统¶
由于缺少维护者,不再支持 OS/2 和 VMS。
由于维护负担,不再支持 Windows 2000 和将 COMSPEC
设置为 command.com
的 Windows 平台。
在 3.2 中已弃用的 OSF 支持已完全删除。
已弃用的 Python 模块、函数和方法¶
将非空字符串传递给
object.__format__()
已被弃用,并且将在 Python 3.4 中产生TypeError
(bpo-9856)。由于 PEP 393,
unicode_internal
编解码器已被弃用,请使用 UTF-8、UTF-16 (utf-16-le
或utf-16-be
) 或 UTF-32 (utf-32-le
或utf-32-be
)platform.popen()
:请使用subprocess
模块。 请特别检查使用 subprocess 模块替换旧函数 部分 (bpo-11377)。bpo-13374:Windows 字节 API 在
os
模块中已被弃用。 请使用 Unicode 文件名,而不是字节文件名,这样就不再依赖 ANSI 代码页,并支持任何文件名。bpo-13988:
xml.etree.cElementTree
模块已弃用。 加速器会在可用时自动使用。time.clock()
的行为取决于平台:请根据您的要求,使用新的time.perf_counter()
或time.process_time()
函数来获得明确的行为。os.stat_float_times()
函数已弃用。abc
模块abc.abstractproperty
已弃用,请改用带有abc.abstractmethod()
的property
。abc.abstractclassmethod
已弃用,请改用带有abc.abstractmethod()
的classmethod
。abc.abstractstaticmethod
已弃用,请改用带有abc.abstractmethod()
的staticmethod
。
-
importlib.abc.SourceLoader.path_mtime()
现在已被弃用,推荐使用importlib.abc.SourceLoader.path_stats()
,因为字节码文件现在存储了编译该字节码文件的源文件的修改时间和大小。
C API 中已弃用的函数和类型¶
Py_UNICODE
已被 PEP 393 弃用,并将在 Python 4 中移除。所有使用此类型的函数都被弃用。
使用 Py_UNICODE
和 Py_UNICODE* 类型的 Unicode 函数和方法
PyUnicode_FromUnicode
: 使用PyUnicode_FromWideChar()
或PyUnicode_FromKindAndData()
PyUnicode_AS_UNICODE
,PyUnicode_AsUnicode()
,PyUnicode_AsUnicodeAndSize()
: 使用PyUnicode_AsWideCharString()
PyUnicode_AS_DATA
: 使用PyUnicode_DATA
以及PyUnicode_READ
和PyUnicode_WRITE
PyUnicode_GET_SIZE
,PyUnicode_GetSize()
: 使用PyUnicode_GET_LENGTH
或PyUnicode_GetLength()
PyUnicode_GET_DATA_SIZE
: 使用PyUnicode_GET_LENGTH(str) * PyUnicode_KIND(str)
(仅适用于已就绪的字符串)PyUnicode_AsUnicodeCopy()
: 使用PyUnicode_AsUCS4Copy()
或PyUnicode_AsWideCharString()
PyUnicode_GetMax()
操作 Py_UNICODE* 字符串的函数和宏
Py_UNICODE_strlen()
: 使用PyUnicode_GetLength()
或PyUnicode_GET_LENGTH
Py_UNICODE_strcat()
: 使用PyUnicode_CopyCharacters()
或PyUnicode_FromFormat()
Py_UNICODE_strcpy()
,Py_UNICODE_strncpy()
,Py_UNICODE_COPY()
: 使用PyUnicode_CopyCharacters()
或PyUnicode_Substring()
Py_UNICODE_strcmp()
: 使用PyUnicode_Compare()
Py_UNICODE_strncmp()
: 使用PyUnicode_Tailmatch()
Py_UNICODE_strchr()
,Py_UNICODE_strrchr()
: 使用PyUnicode_FindChar()
Py_UNICODE_FILL()
: 使用PyUnicode_Fill()
Py_UNICODE_MATCH
编码器
PyUnicode_Encode()
: 使用PyUnicode_AsEncodedObject()
PyUnicode_EncodeUTF7()
PyUnicode_EncodeUTF8()
: 使用PyUnicode_AsUTF8()
或PyUnicode_AsUTF8String()
PyUnicode_EncodeUTF32()
PyUnicode_EncodeUTF16()
PyUnicode_EncodeUnicodeEscape()
使用PyUnicode_AsUnicodeEscapeString()
PyUnicode_EncodeRawUnicodeEscape()
使用PyUnicode_AsRawUnicodeEscapeString()
PyUnicode_EncodeLatin1()
: 使用PyUnicode_AsLatin1String()
PyUnicode_EncodeASCII()
: 使用PyUnicode_AsASCIIString()
PyUnicode_EncodeCharmap()
PyUnicode_TranslateCharmap()
PyUnicode_EncodeMBCS()
: 使用PyUnicode_AsMBCSString()
或PyUnicode_EncodeCodePage()
(使用CP_ACP
code_page)PyUnicode_EncodeDecimal()
,PyUnicode_TransformDecimalToASCII()
已弃用的特性¶
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:
time
和datetime
: 如果时间戳超出范围,现在会引发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_path
和sys.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.Parser
的strict
参数已最终删除。已删除已弃用的方法
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.h
或object.h
中相关部分的扩展都必须重新构建。由于 PEP 393,
Py_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.so
、xxxmodule.abi3.so
和xxxmodule.cpython-*.so
的文件不再被识别为实现xxx
模块。如果您之前生成过此类文件,则必须切换到其他拼写(即,从文件名中删除module
字符串)。(在 bpo-14040 中实现。)