Skip to main content

Python 3.3中的新功能

本文解释了Python 3.3中与3.2相比的新特性。 Python 3.3于2012年9月29日发布。有关完整的详细信息,请参阅 changelog

参见

PEP 398 - Python 3.3发布计划

摘要 - 发布亮点

新的语法特性:

新库模块:

  • 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:新的内存视图实现和缓冲区协议文档

PEP 3118 的实施已经显着改善。

新的内存视图实现全面修复了导致多个崩溃报告的Py_buffer结构中动态分配字段的所有所有权和生命周期问题。此外,几个函数崩溃或返回不连续或多维输入的不正确结果已修复。

memoryview对象现在有一个符合PEP-3118的getbufferproc(),它检查用户的请求类型。添加了许多新功能,其中大多数功能完全通用于非连续数组和具有子操作数组的数组。

文件已更新,清楚地说明了出口商和消费者的责任。缓冲区请求标志分为基本标志和复合标志。解释了非连续和多维NumPy式数组的内存布局。

特征

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

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

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

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

  • 具有格式B,b或c的哈希(只读)类型的一维存储器视图现在是可哈希的。 (供稿人:Antoine Pitrou,issue 13411。)

  • 支持任意1-D阵列类型的任意切片。例如,现在可以通过使用负步长来反转O(1)中的存储器视图。

API更改

  • 正式限制尺寸的最大数量为64个。

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

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

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

  • 有关进一步更改,请参阅 Build and C API ChangesPorting C code

(供稿人:issue 10181 中的Stefan Krah。)

参见

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() 现在总是返回1为非BMP字符,所以 len('\U0010FFFF') == 1

    • 替代对不在字符串文字中重组,因此 '\uDBFF\uDFFF' != '\U0010FFFF'

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

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

  • sys.maxunicode 的值现在总是 1114111 (十六进制的 0x10FFFF)。 PyUnicode_GetMax() 函数仍返回 0xFFFF0x10FFFF 以实现向后兼容性,并且不应与新的Unicode API(参见 issue 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缓存效率。 Python 3.3的内存使用量比Python 3.2小两到三倍,在Django基准测试中比Python 2.7稍微好一些(有关详细信息,请参阅PEP)。

参见

PEP 393 - 灵活字符串表示

PEP由Martin vonLöwis编写;由Torsten Becker和Martin vonLöwis执行。

PEP 397:适用于Windows的Python启动器

Python 3.3 Windows安装程序现在包括一个 py 启动器应用程序,可用于以独立于版本的方式启动Python应用程序。

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

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

除了启动程序,Windows安装程序现在包括一个选项,将新安装的Python添加到系统PATH。 (供稿人:Brian Curtin,issue 3561。)

参见

PEP 397 - 适用于Windows的Python启动器

PEP由Mark Hammond和Martin v。Löwis编写;由Vinay Sajip执行。

Launcher文档:适用于Windows的Python Launcher

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

PEP 3151:重新编写OS和IO异常层次结构

由操作系统错误引发的异常的层次结构现在都被简化和更细粒度。

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

此外,现在更容易捕获特定的错误条件。而不是从 errno 模块检查特定常数的 errno 属性(或 args[0]),您可以捕获足够的 OSError 子类。可用的子类如下:

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 - 重新修改操作系统和IO异常层次结构

PEP由安托万Pitrou编写和实施

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

PEP 380添加 yield from 表达式,允许 generator 将其操作的一部分委托给另一个生成器。这允许将包含 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;文档由ZbigniewJę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由安托万Pitrou编写和实施。

PEP 412:密钥共享字典

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

参见

PEP 412 - 密钥共享字典

PEP由Mark Shannon编写和实施。

PEP 362:函数签名对象

一个新的函数 inspect.signature() 使得python可调用函数的内省简单和直接。支持广泛的callables: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开始,importlib 使用 sys.implementation.cache_tag 来支持 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作为导入的实现

issue 2377 - 替换__import__ w/importlib .__ import__ issue 13959 - 在纯Python中重新实现 imp 的部分 issue 14605 - 使导入机制显式 issue 14646 - 要求加载器设置__loader__和__package__

__import__() 功能现在由 importlib.__import__() 供电。这项工作导致 PEP 302 的“阶段2”的完成。这种变化有多个好处。首先,它允许更多的机械动力进口被暴露,而不是隐含和隐藏在C代码中。它还为支持Python 3.3的所有Python VM提供单一实现,帮助结束导入语义中的任何VM特定的偏差。最后,它减轻了进口的维护,允许未来的增长发生。

对于普通用户,在语义上应该没有可见的改变。对于那些其代码当前以编程方式操作导入或调用导入的人,可能需要的代码更改将在本文档的 Porting Python code 部分中介绍。

新API

这项工作的一个大的好处是暴露了使import语句工作的东西。这意味着,曾经隐含的各种进口商现在作为 importlib 包的一部分已经完全公开。

importlib.abc 中定义的抽象基类已经被扩展以分别通过引入 importlib.abc.MetaPathFinderimportlib.abc.PathEntryFinder 来适当地描述 元路径查找器路径条目查找器 之间。 importlib.abc.Finder 的旧ABC仅提供向后兼容性,并且不强制执行任何方法要求。

在查找器方面,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 中缓存的所有查找器上调用相同名称的方法,以帮助根据需要清除任何存储的状态。

可见更改

有关代码的潜在必需更改,请参阅 Porting Python code 部分。

除了 importlib 现在暴露的范围外,还有其他可见的更改要导入。最大的是,sys.meta_pathsys.path_hooks 现在存储导入使用的所有元路径查找器和路径入口钩子。以前的finders是隐含和隐藏在C代码的import,而不是直接暴露。这意味着,现在可以轻松地删除或更改各种查找器的顺序以适应自己的需要。

另一个变化是所有模块都有一个 __loader__ 属性,存储用于创建模块的加载器。 PEP 302 已经更新,使这个属性是装载器实现所必需的,所以在将来一旦第三方装载器被更新,人们将能够依赖于属性的存在。直到这样的时间,虽然,导入是设置模块后加载。

装载机现在也需要从 PEP 366 设置 __package__ 属性。再一次,导入本身已经在来自 importlib 的所有加载器上设置此属性,并且导入本身是设置后加载属性。

None 现在插入到 sys.path_importer_cache 中,当在 sys.path_hooks 上找不到定位器时。由于 imp.NullImporter 不直接暴露在 sys.path_hooks 上,因此不能再依赖于始终可用作代表未找到定位器的值。

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

(由Brett Cannon执行)

其他语言变化

对核心Python语言所做的一些较小的更改是:

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

    (供稿人:Ezio Melotti,issue 12753。)

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

  • range() 对象上的等式比较现在返回反映这些范围对象生成的基本序列的等同性的结果。 (issue 13201

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

    (供稿人:Petri Lehtinen,issue 12170。)

  • bytesbytearrayrjust()ljust()center() 方法现在接受针对 fill 参数的 bytearray。 (供稿人:Petri Lehtinen,issue 12380。)

  • listbytearray 中添加了新的方法:copy()clear()issue 10516)。因此,MutableSequence 现在还定义 clear() 方法(issue 11388)。

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

    (供稿人:Antoine Pitrou,issue 13748。)

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

    (由FilipGruszczyński提供,issue 13521。)

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

    (由Benjamin Peterson提供)

一个细粒度的导入锁

先前版本的CPython一直依赖于全局导入锁。这导致意想不到的麻烦,例如死锁,当导入模块将触发代码执行在不同的线程作为副作用。有时采用笨拙的解决方法,例如 PyImport_ImportModuleNoBlock() C API函数。

在Python 3.3中,导入模块需要一个每模块锁。这正确地序列化了来自多个线程的给定模块的输入(防止暴露未完全初始化的模块),同时消除上述烦恼。

(供稿人:Antoine Pitrou,issue 9260。)

内置函数和类型

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

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

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

  • str 类型获得一个新的 casefold() 方法:返回一个casefolded字符串的副本,casefolded字符串可以用于无盒匹配。例如,'ß'.casefold() 返回 'ss'

  • 序列文档已被基本重写,以更好地解释二进制/文本序列的区别,并为单个内置序列类型(issue 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

IP地址

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

(由 PEP 3144 中的Google和Peter Moody提供。)

lzma

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

(由Nadeem Vawda和PerØyvindKarlsen提供,在 issue 6715。)

改进模块

abc

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

(供稿:issue 11610 中的Darren Dale。)

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

数组

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

(由Oren Tirosh和Hirokazu Yamamoto在 issue 1172711 中提供)

base64

现在,base64 现代接口的解码功能接受只有ASCII的Unicode字符串。例如,base64.b64decode('YWJj') 返回 b'abc'。 (由Catalin Iacob提供,issue 13641。)

binascii

除了它们通常接受的二进制对象之外,a2b_ 函数现在都接受仅ASCII字符串作为输入。 (供稿人:Antoine Pitrou,issue 13637。)

bz2

bz2 模块已从头重写。在此过程中,增加了几个新功能:

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

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

    (由 issue 5863 中的Nadeem Vawda提供。)

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

    (由NAC Aides在 issue 1625 提供。)

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

编解码器

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

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

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

issue 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.'

此示例为 b'~{Np~}~{J)~}~{l6~}~{HK~}~{!#~} Bye.' 提供了较旧的Python版本。

issue 12100

unicode_internal 编解码器已被弃用。

集合

添加新的 ChainMap 类以允许将多个映射视为单个单元。 (由Raymond Hettinger写的 issue 11089,在 issue 11297 公开。)

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

Counter 类现在支持一元化 +- 运算符,以及就地运算符 +=-=|=&=。 (供稿人:Raymond Hettinger,issue 13121。)

contextlib

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

issue 13585

地穴

crypt 模块添加盐和模块化crypt格式(散列方法)和 mksalt() 函数。

issue 10924

诅咒

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

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

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

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

  • curses 模块有一个新的 unget_wch() 功能推送一个宽字符,所以下一个 get_wch() 将返回它

(由 issue 6755 的IñigoSerna提供)

约会时间

十进制

issue 7652 - 集成快速原生十进制算术。

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

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

性能提升从数据库应用程序的10x到数字密集型应用程序的100x。这些数字是十进制浮点运算中使用的标准精度的预期增益。由于精度是用户可配置的,因此精确的数字可能会有所不同。例如,在整数bignum算术中,差异可以显着更高。

下表用作说明。基准可在 http://www.bytereef.org/mpdecimal/quickstart.html 获得。

 

decimal.py

_decimal

加速

pi

42.02s

0.345s

120x

电信

172.19s

5.68s

30x

psycopg

3.57s

0.29s

12x

特征

  • 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字典。

  • 选择 Context 产生不同的输出,以便具有Python和C版本的公共交换格式。

  • 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

最大长度,不包括lineep字符,个别行可能在 Message 序列化时。默认为78。

lineep

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

cte_type

7bit8bit8bit 仅适用于 Bytes generator,并且意味着可以在协议允许的情况下(或者在原始输入中存在非ASCII)使用非ASCII。

raise_on_defect

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

使用策略对象的 clone() 方法创建具有新设置的新策略实例。 clone 使用任何上述控件作为关键字参数。未在呼叫中指定的任何控制保留其默认值。因此,您可以创建一个使用 \r\n lineep字符的策略,如下所示:

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

策略可用于使应用程序所需的格式的消息生成更简单。在设置 parserMessage 使用的策略(无论您的程序用于创建 Message 对象)时,您都可以指定一次,而不必记住在所有调用 generator 的地方指定 linesep='\r\n'。另一方面,如果您需要生成多种形式的消息,您仍然可以在适当的 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 <foo@example.com>'
>>> m['to']
'Éric <foo@example.com>'
>>> 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?= <foo@example.com>
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='bonz@laugh.com')]
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <foo@example.com>
Date: Fri, 25 May 2012 21:44:27 -0400
cc: pals: Bob <bob@example.com>, Sally <sally@example.com>;, Bonzo <bonz@laugh.com>

解码到unicode是自动完成的:

>>> m2 = message_from_string(str(m))
>>> m2['to']
'Éric <foo@example.com>'

解析消息时,可以使用标题对象的 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)。 (供稿人:issue 8594 的GiampaoloRodolà。)

  • FTP_TLS 类现在提供了一个新的 ccc() 功能,将控制通道恢复为纯文本。这可能有利于利用防火墙知道如何使用非安全FTP处理NAT,而无需打开固定端口。 (由GiampaoloRodolà在 issue 12139。提供)

  • 添加了 ftplib.FTP.mlsd() 方法,它提供可解析的目录列表格式,并弃用 ftplib.FTP.nlst()ftplib.FTP.dir()。 (由GiampaoloRodolà撰写,issue 11072。)

功能

functools.lru_cache() 装饰器现在接受 typed 关键字参数(默认为 False,以确保其缓存在不同缓存槽中比较相等的不同类型的值)(由 issue 13227 中的Raymond Hettinger提供)

GC

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

hmac

添加了新的 compare_digest() 功能以防止通过定时分析对摘要进行侧信道攻击。 (由Nick Coghlan和Christian Heimes提供,issue 15061。)

http

http.server.BaseHTTPRequestHandler 现在缓冲头并在调用 end_headers() 时立即写入所有头。新的方法 flush_headers() 可以用于直接管理何时发送累积的报头。 (由 issue 3709 的Andrew Schaaf提供)

http.server 现在产生有效的 HTML 4.01 strict 输出。 (供稿人:Ezio Melotti,issue 13295。)

http.client.HTTPResponse 现在有一个 readinto() 方法,这意味着它可以用作 io.RawIOBase 类。 (供稿人:John Kuhn,issue 13464。)

html

html.parser.HTMLParser 现在能够解析破坏的标记,而不会引起错误,因此构造函数的 strict 参数和 HTMLParseError 异常现在已被弃用。解析破坏的标记的能力是Python 2.7/3.2的最新错误修复版本中提供的许多错误修复的结果。 (由Ezio Melotti在 issue 15114,和 issue 14538issue 13993issue 13960issue 13358issue 1745761issue 755670issue 13357issue 12629issue 1200313issue 670664issue 13273issue 12888issue 7311 提供)

html.entities 模块中添加了一个新的 html5 字典,用于将HTML5命名的字符引用映射到等效的Unicode字符(例如 html5['gt;'] == '>')。字典现在也被 HTMLParser 使用。 (供稿人:Ezio Melotti,issue 11113issue 15156。)

imaplib

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

(由 issue 8808 中的Sijin Joseph提供)

检查

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

(供稿人:Meador Inge和Nick Coghlan,issue 13062。)

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

(供稿:issue 15153 中的Meador Inge。)

io

open() 功能具有新的 'x' 模式,可用于专门创建新文件,如果文件已存在,则生成 FileExistsError。它基于C11’x’模式到fopen()。

(供稿人:issue 12760 的David Townshend。)

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

itertools

accumulate() 现在采用可选的 func 参数来提供用户提供的二进制函数。

日志

basicConfig() 函数现在支持可选的 handlers 参数,它采用可迭代的处理程序添加到根记录器。

类级别属性 append_nul 已添加到 SysLogHandler 以允许控制将 NUL\000)字节附加到syslog记录,因为对于某些deamons,它是必需的,而对于其他deamons,则将其传递到日志。

数学

math 模块具有新的函数 log2(),其返回 x 的基于2的对数。

(由 issue 11888 中的Mark Dickinson写)。

mmap

read() 方法现在更容易与其他文件类对象兼容:如果参数被省略或指定为 None,它将从当前文件位置返回到映射结束的字节。 (供稿人:issue 12021 的Petri Lehtinen。)

多处理

新的 multiprocessing.connection.wait() 功能允许使用超时轮询多个对象(例如连接,套接字和管道)。 (由Richard Oudkerk贡献于 issue 12328。)

现在可以通过多处理连接传输 multiprocessing.Connection 对象。 (由Richard Oudkerk贡献于 issue 4892。)

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

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

新方法 multiprocessing.pool.Pool.starmap()starmap_async() 为现有的 multiprocessing.pool.Pool.map()map_async() 功能提供 itertools.starmap() 等价物。 (由Hynek Schlawack在 issue 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')
>>>

(由 issue 9795 中的GiampaoloRodolà提供)

os

pdb

制表符完成现在不仅可用于命令名称,还可用于其参数。例如,对于 break 命令,函数和文件名称完成。

(由Georg Brandl在 issue 14210 提供)

泡菜

pickle.Pickler 对象现在具有可选的 dispatch_table 属性,允许设置每个拾取器缩减功能。

(由Richard Oudkerk贡献于 issue 14166。)

pydoc

Tca GUI和 serve() 功能已从 pydoc 模块中删除:pydoc -gserve() 已在Python 3.2中弃用。

回覆

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

(由Serhiy Storchaka提供,issue 3665。)

sched

  • run() 现在接受 blocking 参数,当设置为false时,由于最快到期(如果有),该方法将执行已调度的事件,然后立即返回。如果要在非阻塞应用程序中使用 scheduler,这将非常有用。 (供稿人:issue 13449 的GiampaoloRodolà。)

  • scheduler 类现在可以安全地在多线程环境中使用。 (供稿人:Josiah Carlson和GiampaoloRodolà,issue 8684。)

  • scheduler 类构造函数的 timefuncdelayfunct 参数现在是可选的,默认分别为 time.time()time.sleep()。 (由克里斯·克拉克在 issue 13245。供稿)

  • enter()enterabs() argument 参数现在是可选的。 (供稿人:克里克·克拉克在 issue 13245。)

  • enter()enterabs() 现在接受 kwargs 参数。 (供稿人:克里克·克拉克在 issue 13245。)

选择

Solaris和衍生平台有一个新的类 select.devpoll 通过 /dev/poll 的高性能异步套接字。 (由 issue 6397 的JesúsCeaAvión提供)

shlex

来自 pipes 模块的先前未记录的辅助函数 quote 已被移动到 shlex 模块并记录。 quote() 正确转义字符串中的所有字符,否则该字符串可能由shell给出特殊含义。

shutil

  • 新功能:

    • disk_usage():提供总的,已用的和可用的磁盘空间统计信息。 (供稿人:issue 12442。GiampaoloRodolà。)

    • chown():允许更改给定路径的用户和/或组,还指定用户/组名称,而不仅仅是其数字ID。 (由Sandro Tosi提供,issue 12191。)

    • shutil.get_terminal_size():返回解释器附加的终端窗口的大小。 (供稿人:ZbigniewJędrzejewski-Szmek in issue 13609。)

  • copy2()copystat() 现在在支持它的平台上保留纳秒精度的文件时间戳。它们还在Linux上保留文件“扩展属性”。 (供稿人:Larry Hastings在 issue 14127issue 15238。)

  • 几个函数现在采用可选的 symlinks 参数:当该参数为true时,不解除引用符号链接,并且操作反而作用于符号链接本身(或创建一个,如果相关)。 (由Hynek Schlawack提供,issue 12715。)

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

  • rmtree() 现在抵抗支持 os.open()os.unlink() 中的新 dir_fd 参数的平台上的符号链接攻击。 (由Martin vonLöwis和Hynek Schlawack在 issue 4489。提供)

信号

smtpd

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

(由Alberto Trevino提供的初始 ELHO 支持,Juhana Jauhiainen的大小扩展。由MicheleOrrù和Dan Boswell提供的补丁的大量额外工作。issue 8739

smtplib

SMTPSMTP_SSLLMTP 类现在接受 source_address 关键字参数,以指定在创建传出套接字时在绑定调用中用作源地址的 (host, port)。 (由Paulo Scardine在 issue 11281 提供。)

SMTP 现在支持上下文管理协议,允许在 with 语句中使用 SMTP 实例。 (供稿人:issue 11289 的GiampaoloRodolà。)

SMTP_SSL 构造函数和 starttls() 方法现在接受SSLContext参数以控制安全通道的参数。 (由Kasun Herath在 issue 8809 提供。)

插座

socketserver

BaseServer 现在有一个可覆盖的方法 service_actions(),由服务循环中的 serve_forever() 方法调用。 ForkingMixIn 现在使用它来清理僵尸子进程。 (供稿人:Justin Warkentin,issue 11109。)

sqlite3

新的 sqlite3.Connection 方法 set_trace_callback() 可用于捕获由sqlite处理的所有sql命令的跟踪。 (由Torsten Landschoff提供,issue 11688。)

ssl

stat

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

(由 issue 14807 中的GiampaoloRodolà提供)

结构

struct 模块现在分别通过新代码 nN 支持 ssize_tsize_t。 (供稿人:Antoine Pitrou,issue 3163。)

子过程

命令字符串现在可以是posix平台上的字节对象。 (由Victor Stinner在 issue 8513 提供。)

新的常数 DEVNULL 允许以平台无关的方式抑制输出。 (供稿人:Ross Lagerwall in issue 5870。)

sys

sys 模块有一个新的 thread_info struct sequence,保存有关线程实现(issue 11223)的信息。

tarfile

tarfile 现在支持通过 lzma 模块的 lzma 编码。 (供稿人:LarsGustäbelin issue 5689。)

tempfile

tempfile.SpooledTemporaryFiletruncate() 方法现在接受 size 参数。 (供稿人:Ryan Kelly,issue 9957。)

textwrap

textwrap 模块具有新的 indent(),使得可以直接向文本块(issue 13857)中的选定行添加公共前缀。

线程

threading.Conditionthreading.Semaphorethreading.BoundedSemaphorethreading.Eventthreading.Timer,所有这些都是返回类实例的工厂函数,现在是类,可以是子类。 (由 issue 10968 的Éric Araujo提供)

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

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

时间

PEP 418time 模块添加了新功能:

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

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

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

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

其他新功能:

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

类型

添加新的 types.MappingProxyType 类:映射的只读代理。 (issue 14386

新功能 types.new_class()types.prepare_class() 为符合PEP 3115的动态类型创建提供支持。 (issue 14588

单位测试

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

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

urllib

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

>>> urlopen(Request('https://www.python.org', method='HEAD'))

issue 1673007

网页浏览器

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

xml.etree.ElementTree

xml.etree.ElementTree 模块现在默认导入其C加速器;不再需要显式导入 xml.etree.cElementTree (此模块保留向后兼容性,但现在已弃用)。此外,Element 方法的 iter 家族已经被优化(在C中重写)。通过添加示例和更详细的参考,模块的文档也得到了极大的改进。

zlib

新属性 zlib.Decompress.eof 使得能够区分正确形成的压缩流和不完全或截断的压缩流。 (供稿人:Nadeem Vawda,issue 12646。)

新属性 zlib.ZLIB_RUNTIME_VERSION 报告在运行时加载的基础 zlib 库的版本字符串。 (由Torsten Landschoff提供,issue 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,issue 14624issue 14738issue 15026。)

已弃用

不支持的操作系统

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

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

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

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

不再支持的C API的函数和类型

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

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

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

编码器:

已弃用的功能

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

移植到Python 3.3

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

移植Python代码

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

  • issue 12326:在Linux上,sys.platform不再包含主版本。它现在总是“linux”,而不是“linux2”或“linux3”,这取决于用于构建Python的Linux版本。如果你不需要支持旧的Python版本,请将sys.platform ==’linux2’替换为sys.platform.startswith(’linux’),或直接替换为sys.platform ==’linux’。

  • issue 13847issue 14180timedatetime:如果时间戳超出范围,现在升起 OverflowError 而不是 ValueError。如果C函数 gmtime()localtime() 失败,OSError 现在被引发。

  • 导入使用的默认查找器现在使用特定目录中包含的内容的缓存。如果您创建一个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重新插入 Nonesys.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合规性错误(issue 1079)已被修复。使用标准习语将编码头转换为unicode(str(make_header(decode_header(h)))的代码将看不到更改,但是查看decode_header返回的各个元组的代码将会看到 ASCII 节之前或之后的空格现在包含在 ASCII 节中。使用 make_header 构建头的代码也应该继续工作,而不改变,因为 make_header 继续在 ASCII 和非 ASCII 段之间添加空格(如果输入字符串中不存在空格)。

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

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

  • email.parser.Parserstrict 参数(自Python 2.4以来已弃用)终于被删除。

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

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

  • 已弃用的 Context._clamp 属性已从 decimal 模块中删除。它以前被公共属性 clamp 替换。 (见 issue 8540。)

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

  • 在Windows上向 time.sleep() 传递负值现在会引发错误,而不是永远停止。它总是在posix上引发一个错误。

  • ast.__version__ 常数已删除。如果你需要做决定受AST版本影响,使用 sys.version_info 做出决定。

  • 用于解决 threading 模块通过子类化私有类使用工厂函数的事实的代码需要更改为now-public类的子类。

  • 在线程模块中的未记录的调试机器已被删除,简化了代码。这应该对生产代码没有影响,但是在这里提到任何应用程序调试框架与它交互(issue 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。

Building C扩展

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

    (在 issue 14040 中实施。)

命令行开关更改

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

    issue 10998,由ÉricAraujo提供。)

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

    issue 11591,由Carl Meyer提供,版本为ÉricAraujo。)