Python 3.5 有什么新变化

编者:

Elvis Pranskevichus <elvis@magic.io>, Yury Selivanov <yury@magic.io>

这篇文章介绍了 Python 3.5 相比 3.4 增加的新特性。 Python 3.5 发布于 2015 年 9 月 13 日。 更完整的变化清单请参阅 changelog

参见

PEP 478 - Python 3.5 发布计划

摘要 -- 发布重点

新的语法特性:

  • PEP 492, 使用 async 和 await 语法实现协程。

  • PEP 465, 新的矩阵乘法运算符: a @ b.

  • PEP 448, 额外的解包通用化。

新的库模块:

新的内置特性:

  • bytes % args, bytearray % args: PEP 461 -- 为字节串和字节数组增加 % 格式化。

  • 新增 bytes.hex(), bytearray.hex()memoryview.hex() 方法。 (由 Arnon Yaari 在 bpo-9951 中贡献。)

  • memoryview 现在支持元组索引(包括多维度)。 (由 Antoine Pitrou 在 bpo-23632 中贡献。)

  • 生成器具有一个新的 gi_yieldfrom 属性,它将返回 yield from 表达式所迭代的对象。 (由 Benno Leslie 和 Yury Selivanov 在 bpo-24450 中贡献。)

  • 现在当达到最大递归尝试时将引发新的 RecursionError 异常。 (由 Georg Brandl 在 bpo-19235 中贡献。)

CPython 实现的改进:

  • LC_TYPE 语言区域为 POSIX 语言区域(即 C 语言区域)时,sys.stdinsys.stdout 现在将使用 surrogateescape 错误处理器,而不是 strict 错误处理器。 (由 Victor Stinner 在 bpo-19977 中贡献。)

  • .pyo 文件已不再被使用而是被替换为一个更灵活的方案即在 .pyc 名称中显式地包括优化级别。 (参见 PEP 488 概览。)

  • 内置与扩展模块现在将经过多阶段的过程被初始化,这类似于 Python 模块的加载方式。 (参见 PEP 489 概览。)

标准库中的重大改进:

安全改进:

  • SSLv3 目前在整个标准库中被禁用。 它仍然可以通过手动实例化一个 ssl.SSLContext 来启用。 (请参阅 bpo-22638 了解详情;此修改已向下移植到 CPython 3.4 和 2.7。)

  • HTTP cookie 解析现在将更严格,以防止潜在的注入攻击。 (由 Antoine Pitrou 在 bpo-22796 中贡献。)

Windows改进:

  • 使用新的 Windows 安装器替代了旧版 MSI。 请参阅 在Windows上使用 Python 了解详情。

  • Windows 编译版现在使用 Microsoft Visual C++ 14.0,扩展模块也应当使用同一版本。

请继续阅读有关针对用户的改变的完整清单,包括许多其他较小的改进、CPython 优化、弃用以及潜在的移植问题。

新的特性

PEP 492 - 使用 async 和 await 语法实现协程

PEP 492 通过添加 可等待对象, 协程函数, 异步迭代异步上下文管理器 极大地改善了 Python 对异步编程的支持。

协程函数是使用新的 async def 语法来声明的:

>>> async def coro():
...     return 'spam'

在协程函数内部,新的 await 表达式可用于挂起协程的执行直到其结果可用。 任何对象都可以被 等待,只要它通过定义 __await__() 方法实现了 awaitable 协议。

PEP 492 还增加了 async for 语句用于方便地迭代异步可迭代对象。

一个使用新语法编写的基本 HTTP 客户端示例:

import asyncio

async def http_get(domain):
    reader, writer = await asyncio.open_connection(domain, 80)

    writer.write(b'\r\n'.join([
        b'GET / HTTP/1.1',
        b'Host: %b' % domain.encode('latin-1'),
        b'Connection: close',
        b'', b''
    ]))

    async for line in reader:
        print('>>>', line)

    writer.close()

loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(http_get('example.com'))
finally:
    loop.close()

与异步迭代类似,增加了用于异步上下文管理器的新语法。 以下代码:

import asyncio

async def coro(name, lock):
    print('coro {}: waiting for lock'.format(name))
    async with lock:
        print('coro {}: holding the lock'.format(name))
        await asyncio.sleep(1)
        print('coro {}: releasing the lock'.format(name))

loop = asyncio.get_event_loop()
lock = asyncio.Lock()
coros = asyncio.gather(coro(1, lock), coro(2, lock))
try:
    loop.run_until_complete(coros)
finally:
    loop.close()

将输出:

coro 2: waiting for lock
coro 2: holding the lock
coro 1: waiting for lock
coro 2: releasing the lock
coro 1: holding the lock
coro 1: releasing the lock

请注意 async forasync with 都只能在通过 async def 声明的协程函数中使用。

协程函数应当在兼容的事件循环内部运行,例如 asyncio 循环

备注

在 3.5.2 版本发生变更: 从 CPython 3.5.2 开始,__aiter__ 可以直接返回 异步迭代器。 返回 awaitable 对象将会导致 PendingDeprecationWarning

详情参见文档的 异步迭代器 一节。

参见

PEP 492 -- 使用 async 和 await 语法实现协程

PEP 由 Yury Selivanov 撰写并实现

PEP 465 - 用于矩阵乘法的专用中缀运算符

PEP 465 增加了用于矩阵乘法的 @ 中缀运算符。 目前,还没有内置的 Python 类型实现这个新运算符,不过,它可通过定义 __matmul__(), __rmatmul__()__imatmul__() 分别用于常规、反射和原地矩阵乘法来实现。 这些方法的语义与定义其他中缀算术运算符的方法类似。

矩阵乘法在数学,科学,工程学的许多领域中是一种常见的操作,使用 @ 运算符可以编写更简洁的代码:

S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)

代替:

S = dot((dot(H, beta) - r).T,
        dot(inv(dot(dot(H, V), H.T)), dot(H, beta) - r))

NumPy 1.10 支持新的运算符:

>>> import numpy

>>> x = numpy.ones(3)
>>> x
array([ 1., 1., 1.])

>>> m = numpy.eye(3)
>>> m
array([[ 1., 0., 0.],
       [ 0., 1., 0.],
       [ 0., 0., 1.]])

>>> x @ m
array([ 1., 1., 1.])

参见

PEP 465 -- 用于矩阵乘法的专用中缀运算符

PEP 由 Nathaniel J. Smith 撰写,由 Benjamin Peterson 实现。

PEP 448 - 进一步的解包标准化

PEP 448 扩展了 * 可迭代对象解包操作符和 ** 字典解包操作符的允许使用范围。 现在将可以在 函数调用 中使用任意数量的解包操作:

>>> print(*[1], *[2], 3, *[4, 5])
1 2 3 4 5

>>> def fn(a, b, c, d):
...     print(a, b, c, d)
...

>>> fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4})
1 2 3 4

类似地,元组、列表、集合与字典表示形式也允许多重解包 (参见 表达式列表字典显示):

>>> *range(4), 4
(0, 1, 2, 3, 4)

>>> [*range(4), 4]
[0, 1, 2, 3, 4]

>>> {*range(4), 4, *(5, 6, 7)}
{0, 1, 2, 3, 4, 5, 6, 7}

>>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}

参见

PEP 448 -- 进一步的解包标准化

PEP 由 Joshua Landau 撰写 ,由 Neil Girdhar,Thomas Wouters 和 Joshua Landau 实现。

PEP 461 - 针对 bytes 和 bytearray 的百分号格式化支持

PEP 461 增加了 % 插值运算符bytesbytearray 的支持。

虽然插值通常被认为是一种字符串操作,但在某些情况下针对 bytesbytearrays 的插值操作也是有意义,而弥补这种功能缺失所需的工作可能会影响代码的整体可读性。 在处理通常会混合二进制和 ASCII 兼容文本的 wire 格式化协议时,这个问题尤为重要。

示例:

>>> b'Hello %b!' % b'World'
b'Hello World!'

>>> b'x=%i y=%f' % (1, 2.5)
b'x=1 y=2.500000'

Unicode 对于 %b 来说是不允许的,但对 %a 来说则是可接受的 (等价于 repr(obj).encode('ascii', 'backslashreplace')):

>>> b'Hello %b!' % 'World'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: %b requires bytes, or an object that implements __bytes__, not 'str'

>>> b'price: %a' % '10€'
b"price: '10\\u20ac'"

请注意 %s%r 转换类型虽然受到支持,但应当只被用于需要与 Python 2 保持兼容性的代码中。

参见

PEP 461 -- 为 bytes 和 bytearray 添加 % 格式化

PEP 由 Ethan Furman 撰写 ,由 Neil Schemenauer 和 Ethan Furman 实现。

PEP 484 —— 类型提示

函数标注语法自 3.0 版起即已成为 Python 的特性 (PEP 3107),标注的语义尚未得到定义。

经验表明大多数函数标注的使用都是为了向函数形参和返回值提供类型提示。 很显然如果标准库可以包括用于类型标注的基本定义和工具,对 Python 用户来说将大有裨益。

PEP 484 引入了一个 暂定模块 来提供这些标准定义和工具,以及针对标注不可用的场合的一些惯例。

例如,以下是一个在标注中声明了参数和返回值类型的简单函数:

def greeting(name: str) -> str:
    return 'Hello ' + name

虽然这些标注可在运行时通过常用的 __annotations__ 属性来访问,但是 不会在运行时执行任何类型检查。 相应地,应该有一个单独的离线版类型检查器 (例如 mypy) 被用来按需执行源代码分析。

类型系统支持合并、泛型类型以及名为 Any 的能够适用于所有类型(即作为赋值的来源和目标)的特殊类型。

参见

  • typing 模块文档

  • PEP 484 —— 类型提示

    PEP 由 Guido van Rossum,Jukka Lehtosalo 和 Łukasz Langa 撰写;由 Guido van Rossum 实现。

  • PEP 483 -- 类型提示理论

    PEP 由 Yury Selivanov 撰写

PEP 471 - os.scandir() 函数 -- 一个更好且更快的目录迭代器

PEP 471 向标准库添加了一个新的目录迭代函数 os.scandir()。 此外,os.walk() 现在是使用 scandir 来实现,这使它在 POSIX 系统上可提速 3 至 5 倍而在 Windows 系统上可提速 7 至 20 倍。 这样的效果主要是通过大幅减少遍历目录树所需调用 os.stat() 的次数来达成的。

此外,scandir 是返回一个迭代器,而不是返回一个文件名列表,这提升了迭代非常大的目录时的内存效率。

下面的例子演示了 os.scandir() 的简单用法,显示给定 path 中所有不以 '.' 开头的文件(不包括目录)。 entry.is_file() 调用通常不会执行额外的系统调用:

for entry in os.scandir(path):
    if not entry.name.startswith('.') and entry.is_file():
        print(entry.name)

参见

PEP 471 -- os.scandir() 函数 -- 一个更好且更快的目录迭代器

PEP 由 Ben Hoyt 在 Victor Stinner 的帮助下撰写并实现

PEP 475: 重试返回 EINTR 失败码的系统调用

当一个正在等待 I/O 的系统调用被信号所中断时将会返回一个 errno.EINTR 错误码。 在之前版本中,Python 会在这种情况下引发 InterruptedError。 这意味着在编写 Python 应用程序时,开发者有两种选择:

  1. 忽略 InterruptedError

  2. 处理 InterruptedError 并在每个调用位置尝试重新启动被中断的系统调用。

第一个选项会使应用程序中途出错。 第二个选项添加了大量的额外处理使得代码几乎不可读。 比较:

print("Hello World")

和:

while True:
    try:
        print("Hello World")
        break
    except InterruptedError:
        continue

PEP 475 实现了在 EINTR 时自动重试系统调用。 这移除了大部分场合下在用户代码中处理 EINTRInterruptedError 的负担,并使得 Python 程序,包括标准库的程序更为健壮。 请注意只有在信号处理器未引发异常时系统调用才会被重试。

以下是现在当被信号中断时会被重试的函数的列表:

参见

PEP 475 -- 重试返回 EINTR 失败码的系统调用

PEP 和具体实现由 Charles-François Natali 和 Victor Stinner 撰写,并获得 Antoine Pitrou 的协助(同为法国人)。

PEP 479:更改生成器内部的 StopIteration 处理

生成器与 StopIteration 的交互在 Python 3.4 及更早版本中有时会令人惊讶,并可能隐藏难以觉察的程序错误。 在之前版本中,一个生成器函数内部意外引发的 StopIteration 会被驱动该生成器的循环构造解读为迭代的结束。

PEP 479 更改了生成器的行为:当一个 StopIteration 异常在生成器内部被引发时,它会在其退出生成器所在帧时被替换为 RuntimeError。 这一更改的主要目的是方便在无防护的 next() 调用引发了 StopIteration 并导致生成器所控制的迭代静默地终结的情况下进行调试。 此情况在与 yield from 构造相结合时会特别令人困扰。

这是一个向下不兼容的更改,所以想要启用这个新行为,必须执行 __future__ 导入:

>>> from __future__ import generator_stop

>>> def gen():
...     next(iter([]))
...     yield
...
>>> next(gen())
Traceback (most recent call last):
  File "<stdin>", line 2, in gen
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: generator raised StopIteration

如果未执行 __future__ 导入,当在生成器内部引发 StopIteration 异常时将导致 PendingDeprecationWarning 被引发。

参见

PEP 479 -- 更改生成器内部的 StopIteration 处理

PEP 由 Chris Angelico 和 Guido van Rossum 撰写,由 Chris Angelico,Yury Selivanov 和 Nick Coghlan 实现。

PEP 485:用于测试近似相等的函数

PEP 485 增加了 math.isclose()cmath.isclose() 函数用于检测两个值是否近似相等或称“接近”。 两个值是否接近是根据给定的绝对和相对范围来确定的。 相对范围是 isclose 参数之间的最大允许差值,即相对于较大的那个绝对数值的距离:

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, rel_tol=1e-5)
True
>>> math.isclose(a, b, rel_tol=1e-6)
False

也可以使用绝对范围来比较两个值,它必须是一个非负数值:

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, abs_tol=0.00003)
True
>>> math.isclose(a, b, abs_tol=0.00001)
False

参见

PEP 485 —— 用于测试近似相等的函数

PEP 由 Christopher Barker 撰写,由 Chris Barker 和 Tal Einat 实现。

PEP 486:让 Python 启动器识别虚拟环境

PEP 486 让 Windows 版启动器 (参见 PEP 397) 能够识别激活的虚拟环境。 当要使用默认解释器并且设置了 VIRTUAL_ENV 环境变量时,将使用虚拟环境中的解释器。

参见

PEP 486 -- 让 Python 启动器识别虚拟环境

PEP 由 Paul Moore 撰写并实现

PEP 488:去除 PYO 文件

PEP 488 取消了 .pyo 文件的概念。 这意味着 .pyc 文件将同时代表未优化和已优化的字节码。 为了防止经常需要重新生成字节码文件,现在 .pyc 文件可以在其名称中设置可选的 opt- 标签来表示已优化字节码。 该设置的附带效果是当以 -O-OO 运行时将不会有字节码文件名冲突。 其结果是,使用 -O-OO 生成的字节码现在可以同时存在。 importlib.util.cache_from_source() 专门针对此项变化更新了 API。

参见

PEP 488 -- 去除 PYO 文件

PEP 由 Brett Cannon 撰写并实现。

PEP 489:多阶段扩展模块初始化

PEP 489 更新了扩展模块初始化操作以便利用 Python 3.4 中通过 PEP 451 引入的两步模块加载机制的优势。

这一变化让选择使用新机制的扩展模块的导入语义与 Python 源代码和字节码模块的更为接近,包括可以使用任何有效标识符作为模块名称,而不是仅限于 ASCII。

参见

PEP 489 -- 多阶段扩展模块初始化

PEP 由 Petr Viktorin , Stefan Behnel 和 Nick Coghlan 撰写,由 Petr Viktorin 实现。

其他语言特性修改

对Python 语言核心进行的小改动:

  • 增加了 "namereplace" 错误处理器。 "backslashreplace" 错误处理器现在可用于解码和转译。 (由 Serhiy Storchaka 在 bpo-19676bpo-22286 中贡献。)

  • 现在 -b 选项会影响 bytesint 的比较。 (由 Serhiy Storchaka 在 bpo-23681 中贡献。)

  • 新增 Kazakh kz1048 和 Tajik koi8_t 编解码器。 (由 Serhiy Storchaka 在 bpo-22682bpo-22681 中贡献。)

  • 特征属性文档字符串现在将是可写的。 这对于 collections.namedtuple() 文档字符串特别适用。 (由 Berker Peksag 在 bpo-24064 中贡献。)

  • 涉及相对导入的环形导入现在已受到支持。 (由 Brett Cannon 和 Antoine Pitrou 在 bpo-17636 中贡献。)

新增模块

typing

新增的 typing 暂定 模块提供了对函数类型标注的标准定义和工具。 详情参见 类型提示

zipapp

新增的 zipapp 模块(在 PEP 441 中描述)提供了用于创建可执行 Python Zip 应用程序的 API 和命令行工具,它是根据 bpo-1739468 在 Python 2.6 中引入的,但在当时和之后都没有足够的推广。

使用这个新模块,想要打包你的应用程序只需简单地将所有文件,包括一个 __main__.py 文件放到一个目录 myapp 中并运行:

$ python -m zipapp myapp
$ python myapp.pyz

该模块的实现由 Paul Moore 在 bpo-23491 中贡献。

参见

PEP 441 -- 改进 Python ZIP 应用程序支持

改进的模块

argparse

现在 ArgumentParser 类允许通过将 allow_abbrev 设为 False 来禁用长选项的 缩写用法。 (由 Jonathan Paugh, Steven Bethard, paul j3 和 Daniel Eriksson 在 bpo-14910 中贡献。)

asyncio

由于 asyncio 模块处于 暂定状态,在 Python 3.5 中引入的所有改变都已被向下移植到 Python 3.4.x。

自 Python 3.4.0 开始 asyncio 模块中的重要变化:

3.5.1 中的更新:

3.5.2 中的更新:

bz2

现在 BZ2Decompressor.decompress 方法接受可选的 max_length 参数用来限制解压缩数据的大小上限。 (由 Nikolaus Rath 在 bpo-15955 中贡献。)

cgi

现在 FieldStorage 类已支持 context manager 协议。 (由 Berker Peksag 在 bpo-20289 中贡献。)

cmath

新增函数 isclose() 提供了一种测试近似相等的方式。 (由 Chris Barker 和 Tal Einat 在 bpo-24270 中贡献。)

code

现在 InteractiveInterpreter.showtraceback() 方法将打印完整的回溯链,就像在交互模式解释器中一样。 (由 Claudiu Popa 在 bpo-17442 中贡献。)

collections

现在 OrderedDict 类使用 C 来实现,令其可提速 4 至 100 倍。 (由 Eric Snow 在 bpo-16991 中贡献。)

OrderedDict.items(), OrderedDict.keys(), OrderedDict.values() 等视图现在支持 reversed() 迭代。 (由 Serhiy Storchaka 在 bpo-19505 中贡献。)

deque 类现在定义了 index(), insert()copy(),并且支持 +* 运算符。 这允许 deque 被识别为 MutableSequence 并提升其替代列表的能力。 (由 Raymond Hettinger 在 bpo-23704 中贡献。)

namedtuple() 产生的文档字符串现在可以被更新:

Point = namedtuple('Point', ['x', 'y'])
Point.__doc__ += ': Cartesian coordinate'
Point.x.__doc__ = 'abscissa'
Point.y.__doc__ = 'ordinate'

(由 Berker Peksag 在 bpo-24064 中贡献。)

现在 UserString 类已实现 __getnewargs__(), __rmod__(), casefold(), format_map(), isprintable()maketrans() 类以与对应的 str 方法相匹配。 (由 Joe Jevnik 在 bpo-22189 中贡献。)

collections.abc

现在 Sequence.index() 方法接受 startstop 参数以与对应的 tuple, list 等的方法相匹配。 (由 Devin Jeanpierre 在 bpo-23086 中贡献。)

新增 Generator 抽象基类。 (由 Stefan Behnel 在 bpo-24018 中贡献。)

新增 Awaitable, Coroutine, AsyncIteratorAsyncIterable 抽象基类。 (由 Yury Selivanov 在 bpo-24184 中贡献。)

对于更早的 Python 版本,这些新 ABC 的向下移植版本包含在外部的 PyPI 软件包 之中。

compileall

新增 compileall 选项 -j N,允许同时运行 N 个工作进程来执行并行的字节码编译。 compile_dir() 函数增加了相应的 workers 形参。 (由 Claudiu Popa 在 bpo-16104 中贡献。)

另一个新选项 -r,允许控制最大的子目录递归层级。 (由 Claudiu Popa 在 bpo-19628 中贡献。)

现在可以多次指定 -q 命令行选项,在此情况下,所有输出包括错误都将被抑制。 在 compile_dir(), compile_file()compile_path() 中相应的 quiet 形参现在可接受一个整数值来指明输出抑制的级别。 (由 Thomas Kluyver 在 bpo-21338 中贡献。)

concurrent.futures

现在 Executor.map() 方法接受一个 chunksize 参数以允许在使用 ProcessPoolExecutor() 设置任务批次来提升运行效率。 (由 Dan O'Reilly 在 bpo-11271 中贡献。)

现在 ThreadPoolExecutor 构造器中的工作线程数量是可选的。 默认值为 CPU 数量的 5 倍。 (由 Claudiu Popa 在 bpo-21527 中贡献。)

configparser

现在 configparser 提供了一种方式通过在 ConfigParser 构造器中指定一个由转换器组成的字典,或将它们定义为 ConfigParser 子类中的方法来定制值的转换。 在解析器实例中定义的转换器将被它的节代理所继承。

示例:

>>> import configparser
>>> conv = {}
>>> conv['list'] = lambda v: [e.strip() for e in v.split() if e.strip()]
>>> cfg = configparser.ConfigParser(converters=conv)
>>> cfg.read_string("""
... [s]
... list = a b c d e f g
... """)
>>> cfg.get('s', 'list')
'a b c d e f g'
>>> cfg.getlist('s', 'list')
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> section = cfg['s']
>>> section.getlist('list')
['a', 'b', 'c', 'd', 'e', 'f', 'g']

(由 Łukasz Langa 在 bpo-18159 中贡献。)

contextlib

新增的 redirect_stderr() context manager (类似于 redirect_stdout()) 使得工具脚本更容易处理那些将输出写入到 sys.stderr 并且不提供任何重定向选项的不灵活 API。

>>> import contextlib, io, logging
>>> f = io.StringIO()
>>> with contextlib.redirect_stderr(f):
...     logging.warning('warning')
...
>>> f.getvalue()
'WARNING:root:warning\n'

(由 Berker Peksag 在 bpo-22389 中贡献。)

csv

现在 writerow() 方法可支持任意可迭代对象,而不仅是序列。 (由 Serhiy Storchaka 在 bpo-23171 中贡献。)

curses

新增的 update_lines_cols() 函数可更新 LINESCOLS 模块变量。 这适用于检测手册页屏幕的大小变化。 (由 Arnon Yaari 在 bpo-4254 中贡献。)

dbm

当设置旗标值为 "n"dumb.open 将总是创建新的数据库。 (由 Claudiu Popa 在 bpo-18039 中贡献。)

difflib

HtmlDiff.make_file() 生成的 HTML 文档的字符集现在可通过使用新增的 charset 仅限关键字参数来自定义。 HTML 文档的默认字符集已从 "ISO-8859-1" 改为 "utf-8"。 (由 Berker Peksag 在 bpo-2052 中贡献。)

现在 diff_bytes() 函数可能比较字节串的列表。 这修复了一个来自 Python 2 遗留总是。 (由 Terry J. Reedy 和 Greg Ward 在 bpo-17445 中贡献。)

distutils

现在 buildbuild_ext 命令都接受一个 -j 选项以启用扩展模块的并行编译。 (由 Antoine Pitrou 在 bpo-5309 中贡献。)

现在 distutils 模块支持 xz 压缩,并可通过将 xztar 作为传给 bdist --format 的参数来启用。 (由 Serhiy Storchaka 在 bpo-16314 中贡献。)

doctest

如果 module 不包含任何文档字符串则 DocTestSuite() 函数将返回一个空的 unittest.TestSuite,而不是引发 ValueError。 (由 Glenn Jones 在 bpo-15916 中贡献。)

email

新增的策略选项 Policy.mangle_from_ 可控制生成器是否要为电子邮件消息体中以controls whether or not lines that start with "From " 打头的行添加 ">" 字符前缀。 默认 compat32True 而所有其他策略均为 False。 (由 Milan Oberkirch 在 bpo-20098 中贡献。)

新增的 Message.get_content_disposition() 方法可提供对 Content-Disposition 标头规范值的便捷访问。 (由 Abhilash Raj 在 bpo-21083 中贡献。)

新增的策略选项 EmailPolicy.utf8 可被设为 True 以使用 UTF-8 字符集而不是使用已编码的字来编码电子邮件标头。 这将允许根据 RFC 6532 来格式化 Messages 并配合支持 RFC 6531 SMTPUTF8 扩展的 SMTP 服务器使用。 (由 R. David Murray 在 bpo-24211 中贡献。)

现在 mime.text.MIMEText 构造器可接受一个 charset.Charset 实例。 (由 Claude Paroz 和 Berker Peksag 在 bpo-16324 中贡献。)

enum

Enum 可调用对象新增了一个形参 start 用于在只提供了 names 的情况下指定枚举值的初始数量:

>>> Animal = enum.Enum('Animal', 'cat dog', start=10)
>>> Animal.cat
<Animal.cat: 10>
>>> Animal.dog
<Animal.dog: 11>

(由 Ethan Furman 在 bpo-21706 中贡献。)

faulthandler

现在 enable(), register(), dump_traceback()dump_traceback_later() 函数除了接受文件型对象以外也接受文件描述符。 (由 Wei Wu 在 bpo-23566 中贡献。)

functools

现在大部分 lru_cache() 机制已使用 C 实现,使其速度显著提升。 (由 Matt Joiner, Alexey Kachayev 和 Serhiy Storchaka 在 bpo-14373 中贡献。)

glob

现在 iglob()glob() 函数支持通过使用 "**" 模式在子目录中递归搜索。 (由 Serhiy Storchaka 在 bpo-13968 中贡献。)

gzip

现在 GzipFile 构造器的 mode 参数可接受 "x" 来请求独占式的创建。 (由 Tim Heaney 在 bpo-19222 中贡献。)

heapq

现在 merge() 中的元素比较可通过在新增的可选关键字参数 key 中传入一个 key function 来进行定制,并且新增了可选关键字参数 reverse 用于反向的元素比较:

>>> import heapq
>>> a = ['9', '777', '55555']
>>> b = ['88', '6666']
>>> list(heapq.merge(a, b, key=len))
['9', '88', '777', '6666', '55555']
>>> list(heapq.merge(reversed(a), reversed(b), key=len, reverse=True))
['55555', '6666', '777', '88', '9']

(由 Raymond Hettinger 在 bpo-13742 中贡献。)

http

新增的 HTTPStatus 枚举定义了一组 HTTP 状态码、英文短说明和长描述。 (由 Demian Brecht 在 bpo-21793 中贡献。)

http.client

现在 HTTPConnection.getresponse() 在远程服务器连接被意外关闭时会引发 RemoteDisconnected 异常。 此外,如果引发了 ConnectionError (RemoteDisconnected 是其子类),客户端套接字现在会自动关闭,并将在下次请求时重新连接:

import http.client
conn = http.client.HTTPConnection('www.python.org')
for retries in range(3):
    try:
        conn.request('GET', '/')
        resp = conn.getresponse()
    except http.client.RemoteDisconnected:
        pass

(由 Martin Panter 在 bpo-3566 中贡献。)

idlelib 与 IDLE

由于 idlelib 实现了 IDLE 命令行界面和编辑器且不应被其他程序导入,它将随每个发布版获得不断改进。 请参阅 Lib/idlelib/NEWS.txt 查看 3.4.0 以来的累积改变列表,以及未来 3.5.x 发布版将进行的改变。 此文件也可通过 IDLE Help ‣ About IDLE 对话框查看。

imaplib

现在 IMAP4 类已支持 context manager 协议。 当用于 with 语句时,IMAP4 LOGOUT 命令将在代码块的末尾被自动调用。 (由 Tarek Ziadé 和 Serhiy Storchaka 在 bpo-4972 中贡献。)

现在 imaplib 模块已通过 IMAP4.enable() 方法支持 RFC 5161 (ENABLE 扩展) 和 RFC 6855 (UTF-8 支持)。 新增的 IMAP4.utf8_enabled 属性可跟踪 RFC 6855 支持是否被启用。 (由 Milan Oberkirch, R. David Murray 和 Maciej Szulik 在 bpo-21800 中贡献。)

现在 imaplib 模块会自动使用 UTF-8 自动编码非 ASCII 字符串的用户名和密码,如 RFC 所建议的那样。 (由 Milan Oberkirch 在 bpo-21800 中贡献。)

imghdr

现在 what() 函数可识别 OpenEXR 格式(由 Martin Vignali 和 Claudiu Popa 在 bpo-20295 中贡献),以及 WebP 格式(由 Fabrice Aneche 和 Claudiu Popa 在 bpo-20197 中贡献。)

importlib

util.LazyLoader 类允许在对启动时间敏感的应用程序中使用模块的惰性加载。 (由 Brett Cannon 在 bpo-17621 中贡献。)

现在 abc.InspectLoader.source_to_code() 方法属于静态方法。 这样将可更方便地通过运行 exec(code, module.__dict__) 基于字符串编译的代码来初始化模块。 (由 Brett Cannon 在 bpo-21156 中贡献。)

新增的 util.module_from_spec() 函数现在是创建新模块的首先方式。 相比直接创建 types.ModuleType 实例,这个新函数将基于传入的规格说明对象设置各种导入控制的属性。 (由 Brett Cannon 在 bpo-20383 中贡献。)

inspect

现在 SignatureParameter 类都是可封存和可哈希的对象。 (由 Yury Selivanov 在 bpo-20726bpo-20334 中贡献。)

新增的 BoundArguments.apply_defaults() 方法提供了一种为缺失的参数设置默认值的方式:

>>> def foo(a, b='ham', *args): pass
>>> ba = inspect.signature(foo).bind('spam')
>>> ba.apply_defaults()
>>> ba.arguments
OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())])

(由 Yury Selivanov 在 bpo-24190 中贡献。)

新增的类方法 Signature.from_callable() 使得 Signature 的子类化更为容易。 (由 Yury Selivanov 和 Eric Snow 在 bpo-17373 中贡献。)

现在 signature() 函数接受 follow_wrapped 可选关键字参数,当其设为 False 时,将禁用 __wrapped__ 链接的自动跟随。 (由 Yury Selivanov 在 bpo-20691 中贡献。)

新增了一组用于检查 协程函数协程对象 的函数: iscoroutine(), iscoroutinefunction(), isawaitable(), getcoroutinelocals()getcoroutinestate()。 (由 Yury Selivanov 在 bpo-24017bpo-24400 中贡献。)

现在 stack(), trace(), getouterframes()getinnerframes() 函数将返回具名元组的列表。 (由 Daniel Shahaf 在 bpo-16808 中贡献。)

io

新增 BufferedIOBase.readinto1() 方法,该方法会使用至少一次对下层原始流的调用 RawIOBase.read()RawIOBase.readinto() 方法。 (由 Nikolaus Rath 在 bpo-20578 中贡献。)

ipaddress

现在 IPv4NetworkIPv6Network 类均接受一个 (address, netmask) 元组参数,可以根据现有地址方便地构造网络对象:

>>> import ipaddress
>>> ipaddress.IPv4Network(('127.0.0.0', 8))
IPv4Network('127.0.0.0/8')
>>> ipaddress.IPv4Network(('127.0.0.0', '255.0.0.0'))
IPv4Network('127.0.0.0/8')

(由 Peter Moody 和 Antoine Pitrou 在 bpo-16531 中贡献。)

新增 IPv4NetworkIPv6Network 类的 reverse_pointer 属性用于返回 DNS PTR 反向记录的名称:

>>> import ipaddress
>>> addr = ipaddress.IPv4Address('127.0.0.1')
>>> addr.reverse_pointer
'1.0.0.127.in-addr.arpa'
>>> addr6 = ipaddress.IPv6Address('::1')
>>> addr6.reverse_pointer
'1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa'

(由 Leon Weber 在 bpo-20480 中贡献。)

json

现在 json.tool 命令行接口会保留输入中传入的 JSON 对象中键的顺序。 新的 --sort-keys 选项可用于按字母顺序对键进行排序。 (由 Berker Peksag 在 bpo-21650 中贡献。)

现在 JSON 解码器会引发 JSONDecodeError 而不是 ValueError 以提供有关错误的更好的上下文信息。 (由 Serhiy Storchaka 在 bpo-19361 中贡献。)

linecache

新增的 lazycache() 函数可用于捕获非基于文件的模块 的信息以允许在此后通过 getline() 获取其行数据。 这样就可以避免在实际需要某一行之前执行 I/O 操作,从而不需要无限期地持有模块 globals。 (由 Robert Collins 在 bpo-17911 中贡献。)

locale

新增的 delocalize() 函数可用于将字符串转换为表示规范化数字的字符串 ,并会考虑 LC_NUMERIC 的设置:

>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC, 'de_DE.UTF-8')
'de_DE.UTF-8'
>>> locale.delocalize('1.234,56')
'1234.56'
>>> locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.delocalize('1,234.56')
'1234.56'

(由 Cédric Krier 在 bpo-13918 中贡献。)

logging

所有日志记录方法(如 Logger log(), exception(), critical(), debug() 等)的 exc_info 参数现在除接受布尔值和异常元组以外,也接受异常实例:

>>> import logging
>>> try:
...     1/0
... except ZeroDivisionError as ex:
...     logging.error('exception', exc_info=ex)
ERROR:root:exception

(由 Yury Selivanov 在 bpo-20537 中贡献。)

现在 handlers.HTTPHandler 类接受一个可选的 ssl.SSLContext 实例来配置在 HTTP 连接中使用的 SSL 设置。 (由 Alex Gaynor 在 bpo-22788 中贡献。)

现在 handlers.QueueListener 类接受一个 respect_handler_level 关键字参数,如果将该参数设为 True,会向处理器传递消息以将处理器级别纳入考量。 (由 Vinay Sajip 贡献。)

lzma

现在 LZMADecompressor.decompress() 方法接受一个可选的 max_length 参数用来限制解压缩数据的大小上限。 (由 Martin Panter 在 bpo-15955 中贡献。)

math

math 模块增加了两个新常量: infnan。 (由 Mark Dickinson 在 bpo-23185 中贡献。)

新增函数 isclose() 提供了一种测试近似相等的方式。 (由 Chris Barker 和 Tal Einat 在 bpo-24270 中贡献。)

新增 gcd() 函数。 现在 fractions.gcd() 函数已被弃用。 (由 Mark Dickinson 和 Serhiy Storchaka 在 bpo-22486 中贡献。)

multiprocessing

现在 sharedctypes.synchronized() 对象支持 context manager 协议。 (由 Charles-François Natali 在 bpo-21565 中贡献。)

operator

现在 attrgetter(), itemgetter()methodcaller() 对象支持封存操作。 (由 Josh Rosenberg 和 Serhiy Storchaka 在 bpo-22955 中贡献。)

新增 matmul()imatmul() 函数用于执行矩阵乘法。 (由 Benjamin Peterson 在 bpo-21176 中贡献。)

os

新增 scandir() 函数可返回一个 DirEntry 对象的迭代器。 如有可能,scandir() 会在扫描目录时提取文件属性,不必再执行后续的系统调用来确定文件类型或属性,这可以显著提升运行效率。 (由 Ben Hoyt 在 bpo-22524 并得到 Victor Stinner 的协助。)

在 Windows 上,现在可使用新的 stat_result.st_file_attributes 属性。 它对应于 GetFileInformationByHandle() 所返回的 BY_HANDLE_FILE_INFORMATION 结构体的 dwFileAttributes 成员。 (由 Ben Hoyt 在 bpo-21719 中贡献。)

现在 urandom() 函数在 Linux 3.17 或更新的系统上会使用 getrandom() 系统调用,而在 OpenBSD 5.6 或更新的系统上会使用 getentropy(),不必再使用 /dev/urandom 并避免由于潜在的文件描述符耗尽导致的执行失败。 (由 Victor Stinner 在 bpo-22181 中贡献。)

新增的 get_blocking()set_blocking() 函数允许获取和设置文件描述符的阻塞模式 (O_NONBLOCK)。 (由 Victor Stinner 在 bpo-22054 中贡献。)

现在 truncate()ftruncate() 函数在 Windows 上已受到支持。 (由 Steve Dower 在 bpo-23668 中贡献。)

新增的 os.path.commonpath() 函数可返回所传入的每个路径名的最长共同子路径。 与 os.path.commonprefix() 函数不同,该函数总是会返回一个有效的路径:

>>> os.path.commonprefix(['/usr/lib', '/usr/local/lib'])
'/usr/l'

>>> os.path.commonpath(['/usr/lib', '/usr/local/lib'])
'/usr'

(由 Rafik Draoui 和 Serhiy Storchaka 在 bpo-10395 中贡献。)

pathlib

新增的 Path.samefile() 方法可被用来检查一个路径是否与另一个路径指向相同的文件,两个路径可以是 Path 对象,也可以是字符串:

>>> import pathlib
>>> p1 = pathlib.Path('/etc/hosts')
>>> p2 = pathlib.Path('/etc/../etc/hosts')
>>> p1.samefile(p2)
True

(由 Vajrasky Kok 和 Antoine Pitrou 在 bpo-19775 中贡献。)

现在 Path.mkdir() 方法接受一个新的 exist_ok 可选参数以与 mkdir -pos.makedirs() 的功能相匹配。 (由 Berker Peksag 在 bpo-21539 中贡献。)

新增了一个 Path.expanduser() 方法用于扩展 ~~user 前缀。 (由 Serhiy Storchaka 和 Claudiu Popa 在 bpo-19776 中贡献。)

新增的 Path.home() 类方法可被用于获取代表用户家目录的 Path 实例。 (由 Victor Salgado 和 Mayank Tripathi 在 bpo-19777 中贡献。)

新增 Path.write_text(), Path.read_text(), Path.write_bytes(), Path.read_bytes() 方法用于简化对文件的读/写操作。

以下代码片段将创建或重写现有的文件 ~/spam42:

>>> import pathlib
>>> p = pathlib.Path('~/spam42')
>>> p.expanduser().write_text('ham')
3

(由 Christopher Welborn 在 bpo-20218 中贡献。)

pickle

嵌套的对象,例如未绑定方法或嵌套的类,现在可以使用早于协议版本 4 的 pickle 协议。 协议版本 4 在此前已支持此种场景。 (由 Serhiy Storchaka 在 bpo-23611 中贡献。)

poplib

新增 POP3.utf8() 命令可以启用 RFC 6856 (国际化 Email) 支持,如果 POP 服务器支持的话。 (由 Milan OberKirch 在 bpo-21804 中贡献。)

re

现在对固定长度分组的引用和有条件引用在后视断言中已被允许:

>>> import re
>>> pat = re.compile(r'(a|b).(?<=\1)c')
>>> pat.match('aac')
<_sre.SRE_Match object; span=(0, 3), match='aac'>
>>> pat.match('bbc')
<_sre.SRE_Match object; span=(0, 3), match='bbc'>

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

在正则表达式中捕获分组的数量不再有 100 个的上限。 (由 Serhiy Storchaka 在 bpo-22437 中贡献。)

现在 sub()subn() 函数将用空字符串替换不匹配的分组而不是引发异常。 (由 Serhiy Storchaka 在 bpo-1519638 中贡献。)

re.error 异常添加了新的属性 msg, pattern, pos, linenocolno,以提供更详细的错误上下文信息:

>>> re.compile("""
...     (?x)
...     .++
... """)
Traceback (most recent call last):
   ...
sre_constants.error: multiple repeat at position 16 (line 3, column 7)

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

readline

新增的 append_history_file() 函数可被用于将历史数据中指定数量的末尾元素添加到给定的文件中。 (由 Bruno Cauet 在 bpo-22940 中贡献。)

selectors

新增的 DevpollSelector 在 Solaris 上支持高效的 /dev/poll 轮询。 (由 Giampaolo Rodola' 在 bpo-18931 中贡献。)

shutil

现在 move() 函数现在接受一个 copy_function 参数,举例来说,如果需要在移动文件时忽略其元数据,可以使用 copy() 函数来代替默认的 copy2()。 (由 Claudiu Popa 在 bpo-19840 中贡献。)

现在 make_archive() 函数已支持 xztar 格式。 (由 Serhiy Storchaka 在 bpo-5411 中贡献。)

signal

在 Windows 上,现在 set_wakeup_fd() 函数还可以支持套接字句柄。 (由 Victor Stinner 在 bpo-22018 中贡献。)

signal 模块中的各个 SIG* 常量已被转换为 枚举。 这允许在调试期间打印有意义的名称,而不是整数类型的“魔法数字”。 (由 Giampaolo Rodola' 在 bpo-21076 中贡献。)

smtpd

Both the SMTPServer and SMTPChannel classes now accept a decode_data keyword argument to determine if the DATA portion of the SMTP transaction is decoded using the "utf-8" codec or is instead provided to the SMTPServer.process_message() method as a byte string. The default is True for backward compatibility reasons, but will change to False in Python 3.6. If decode_data is set to False, the process_message method must be prepared to accept keyword arguments. (Contributed by Maciej Szulik in bpo-19662.)

The SMTPServer class now advertises the 8BITMIME extension (RFC 6152) if decode_data has been set True. If the client specifies BODY=8BITMIME on the MAIL command, it is passed to SMTPServer.process_message() via the mail_options keyword. (Contributed by Milan Oberkirch and R. David Murray in bpo-21795.)

The SMTPServer class now also supports the SMTPUTF8 extension (RFC 6531: Internationalized Email). If the client specified SMTPUTF8 BODY=8BITMIME on the MAIL command, they are passed to SMTPServer.process_message() via the mail_options keyword. It is the responsibility of the process_message method to correctly handle the SMTPUTF8 data. (Contributed by Milan Oberkirch in bpo-21725.)

现在可以在 SMTPServer 构造器中,直接或通过名称解析来提供 IPv6 地址,并使其成功连接。 (由 Milan Oberkirch 在 bpo-14758 中贡献。)

smtplib

新增的 SMTP.auth() 方法为实现自定义身份验证机制提供了一个便捷的方式。 (由 Milan Oberkirch 在 bpo-15014 中贡献。)

现在 SMTP.set_debuglevel() 方法可接受额外的 debuglevel (2),它将在调试消息中启用时间戳。 (由 Gavin Chappell 和 Maciej Szulik 在 bpo-16914 中贡献。)

现在 SMTP.sendmail()SMTP.send_message() 方法均支持 RFC 6531 (SMTPUTF8)。 (由 Milan Oberkirch 和 R. David Murray 在 bpo-22027 中贡献。)

sndhdr

现在 what()whathdr() 函数将返回 namedtuple()。 (由 Claudiu Popa 在 bpo-18615 中贡献。).)

socket

现在函数的超时设置将使用单调时钟,而不是系统时钟。 (由 Victor Stinner 在 bpo-22043 中贡献。)

新增的 socket.sendfile() 方法允许在 UNIX 上使用高性能的 os.sendfile() 函数通过套接字发送文件,使得上传速度比使用简单的 socket.send() 快 2 至 3 倍。 (由 Giampaolo Rodola' 在 bpo-17552 中贡献。)

socket.sendall() 方法每次接受或发送字节数据时将不再重置套接字超时。 现在套接字超时将为发送所有数据最大总计持续时间。 (由 Victor Stinner 在 bpo-23853 中贡献。)

现在 socket.listen() 方法的 backlog 参数将是可选的。 在默认情况下它会被设为 SOMAXCONN128,取其中的较小值。 (由 Charles-François Natali 在 bpo-21455 中贡献。)

ssl

内存 BIO 支持

(由 Geert Jansen 在 bpo-21965 中贡献。)

新增了 SSLObject 类以针对 SSLSocket 的网络 I/O 能力是非必要或未优化的情况提供 SSL 协议支持。 SSLObject 代表一个 SSL 协议实例,但不实现任何网络 I/O 方法,而是提供一个内存缓冲区接口。 新增的 MemoryBIO 类可被用于在 Python 和 SSL 协议实例之间传递数据。

内存 BIO SSL 支持主要被用来为对 SSLSocket 的就绪模型("选择/轮询")来说效率较低的框架实现异步 I/O。

新增的 SSLContext.wrap_bio() 方法可被用于创建新的 SSLObject 实例。

应用层协议协商支持

(由 Benjamin Peterson 在 bpo-20188 中贡献。)

如果有 OpenSSL 支持,现在 ssl 模块可实现 RFC 7301 中描述的 应用层协议协商 TLS 扩展。

新增的 SSLContext.set_alpn_protocols() 可被用来指定在 TLS 握手期间套接字所要应用的协议。

新增的 SSLSocket.selected_alpn_protocol() 可返回在 TLS 握手期间所选择的协议。 HAS_ALPN 旗标用于指明是否提供了 ALPN 支持。

其他改变

新增 SSLSocket.version() 方法以便查询实际使用的协议。 (由 Antoine Pitrou 在 bpo-20421 中贡献。)

现在 SSLSocket 类已实现了 SSLSocket.sendfile() 方法。 (由 Giampaolo Rodola' 在 bpo-17552 中贡献。)

现在当操作将要阻塞时 SSLSocket.send() 方法将在非阻塞的套接字上引发 ssl.SSLWantReadErrorssl.SSLWantWriteError 异常。 在之前版本中,它将返回 0。 (由 Nikolaus Rath 在 bpo-20951 中贡献。)

根据 RFC 5280,现在 cert_time_to_seconds() 函数会将输入的时间解读为 UTC 而不是本地时间。 此外,其返回值必定为 int。 (由 Akira Li 在 bpo-19940 中贡献。)

新增的 SSLObject.shared_ciphers()SSLSocket.shared_ciphers() 方法将返回客户端在握手期间中发送的密码列表。 (由 Benjamin Peterson 在 bpo-23186 中贡献。)

SSLSocket 类的 SSLSocket.do_handshake(), SSLSocket.read(), SSLSocket.shutdown()SSLSocket.write() 方法在每次接收或发送字节数据时将不再重置套接字超时。 现在套接字超时将为方法的最长运行时间。 (由 Victor Stinner 在 bpo-23853 中贡献。)

现在 match_hostname() 函数也支持 IP 地址的匹配。 (由 Antoine Pitrou 在 bpo-23239 中贡献。)

sqlite3

现在 Row 类可完整支持序列协议,特别是 reversed() 迭代和切片索引。 (由 Claudiu Popa 在 bpo-10203 中贡献;由 Lucas Sinclair, Jessica McKellar 和 Serhiy Storchaka 在 bpo-13583 中贡献。)

subprocess

新增了 run() 函数。 它可运行指定的命令并返回一个 CompletedProcess 对象,该对象表示已结束的进程。 这个新 API 有更好的一致性并且是在 Python 中发起调用子进程的推荐方式,它不需要维持与更早的 Python 的兼容性。 (由 Thomas Kluyver 在 bpo-23342 中贡献。)

示例:

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

sys

新增的 set_coroutine_wrapper() 函数允许设置一个要在 协程对象async def 函数创建时被调用的全局钩子。 可以使用相应的 get_coroutine_wrapper() 来获取当前设置的包装器。 这两个函数均为 暂定状态,并应当仅用于调试目的。 (由 Yury Selivanov 在 bpo-24017 中贡献。)

新增的 is_finalizing() 函数可用于检测 Python 解释器是否 正在关闭。 (由 Antoine Pitrou 在 bpo-22696 中贡献。)

sysconfig

在 Windows 上用户脚本的名称现在将包括 Python 版本号的前两个数字。 (由 Paul Moore 在 bpo-23437 中贡献。)

tarfile

现在 open() 函数的 mode 参数可接受 "x" 来请求独占式的创建。 (由 Berker Peksag 在 bpo-21717 中贡献。)

现在 TarFile.extractall()TarFile.extract() 方法可接受关键字参数 numeric_owner。 如果设为 True,解压的文件和目录将归属于 tar 文件保存的数字 uidgid。 如果设为 False (默认值,也是 3.5 之前版本的行为),则它们将归属于 tar 文件保存的用户和组名称。 (由 Michael Vogt 和 Eric Smith 在 bpo-23193 中贡献。)

现在 TarFile.list() 接受可选的 members 关键字参数,它可被设为 TarFile.getmembers() 所返回的列表的一个子集。 (由 Serhiy Storchaka 在 bpo-21549 中贡献。)

threading

现在 Lock.acquire()RLock.acquire() 方法均使用单调时钟进行超时管理。 (由 Victor Stinner 在 bpo-22043 中贡献。)

time

现在 monotonic() 函数将总是可用。 (由 Victor Stinner 在 bpo-22043 中贡献。)

timeit

新增的命令行选项 -u--unit=U 可被用于指定计时器输出的时间单位。 受支持的选项有 usec, msecsec。 (由 Julian Gindi 在 bpo-18983 中贡献。)

timeit() 函数新增了 globals 形参用于指定代码运行所在的命名空间。 (由 Ben Roberts 在 bpo-2527 中贡献。).)

tkinter

用于在 Windows 上设置 Tcl/Tk 环境的 tkinter._fix 模块已被 _tkinter 模块中的私有函数所替换,该函数不会永久性修改环境变量。 (由 Zachary Ware 在 bpo-20035 中贡献。)

回溯

新增的 walk_stack()walk_tb() 函数可方便地遍历帧和 回溯对象。 (由 Robert Collins 在 bpo-17911 中贡献。)

新增轻量级的类: TracebackException, StackSummaryFrameSummary。 (由 Robert Collins 在 bpo-17911 中贡献。)

现在 print_tb()print_stack() 函数均支持 limit 参数使用负值。 (由 Dmitry Kazakov 在 bpo-22619 中贡献。).)

types

新增 coroutine() 函数用于将 生成器生成器型 对象转换为 可等待对象。 (由 Yury Selivanov 在 bpo-24017 中贡献。)

新增一个名为 CoroutineType 的类型,用于由 async def 函数创建的 coroutine 对象。 (由 Yury Selivanov 在 bpo-24400 中贡献。)

unicodedata

现在 unicodedata 模块使用来自 Unicode 8.0.0 的数据。

unittest

现在 TestLoader.loadTestsFromModule() 方法可接受仅限关键字参数 pattern,它将作为传给 load_tests 的第三个参数。 找到的包无论其路径是否匹配 pattern 都会针对 load_tests 进行检查,因为包名不可能与默认模式相匹配。 (由 Robert Collins 和 Barry A. Warsaw 在 bpo-16662 中贡献。)

单元测试发现错误现在将会暴露为 TestLoaderTestLoader.errors 属性。 (由 Robert Collins 在 bpo-19746 中贡献。)

新增的命令行选项 --locals 可显示回溯中的局部变量。 (由 Robert Collins 在 bpo-22936 中贡献。)

unittest.mock

Mock 类具有以下改进:

  • 类构造器新增了 unsafe 形参,它可导致模拟对象在名称以 "assert" 打头的属性名上引发 AttributeError。 (由 Kushal Das 在 bpo-21238 中贡献。)

  • 新增了 Mock.assert_not_called() 方法用于检测模拟对象是否已被调用。 (由 Kushal Das 在 bpo-21262 中贡献。)

现在 MagicMock 类已支持 __truediv__(), __divmod__()__matmul__() 运算符。 (由 Johannes Baiter 在 bpo-20968 中贡献,并由 Håkan Lövdahl 在 bpo-23581bpo-23568 中贡献。)

在对内置名称打补丁时不再需要显式地将 create=True 传给 patch() 函数。 (由 Kushal Das 在 bpo-17660 中贡献。)

urllib

新增的 request.HTTPPasswordMgrWithPriorAuth 类允许对 HTTP 基本认证凭据进行管理以消除不必要的 401 响应处理,或在第一次请求时无条件地发送凭据,以便与返回 404 响应的服务器通信而不是在未发送 Authorization 头信息的情况下发送 401。 (由 Matej Cepl 在 bpo-19494 以及 Akshit Khurana 在 bpo-7159 中贡献。)

parse.urlencode() 函数新增的 quote_via 参数提供了一种在需要时控制查询部分的编码格式的手段。 (由 Samwyse 和 Arnon Yaari 在 bpo-13866 中贡献。)

request.urlopen() 函数接受 ssl.SSLContext 对象作为 context 参数,它将被用于 HTTPS 连接。 (由 Alex Gaynor 在 bpo-22366 中贡献。).)

parse.urljoin() 已获得更新已使用 RFC 3986 语义来解析相对 URL,而不是 RFC 1808RFC 2396。 (由 Demian Brecht 和 Senthil Kumaran 在 bpo-22118 中贡献。)

wsgiref

现在 headers.Headers 类构造器的 headers 参数将是可选的。 (由 Pablo Torres Navarrete 和 SilentGhost 在 bpo-5800 中贡献。)

xmlrpc

现在 client.ServerProxy 类已支持 context manager 协议。 (由 Claudiu Popa 在 bpo-20627 中贡献。)

现在 client.ServerProxy 构造器接受可选的 ssl.SSLContext 实例。 (由 Alex Gaynor 在 bpo-22960 中贡献。)

xml.sax

现在 SAX 解析器已支持 xmlreader.InputSource 对象的字符流。 (由 Serhiy Storchaka 在 bpo-2175 中贡献。)

现在 parseString() 接受 str 实例。 (由 Serhiy Storchaka 在 bpo-10590 中贡献。)

zipfile

现在可以将 ZIP 输出写入到不可定位的流。 (由 Serhiy Storchaka 在 bpo-23252 中贡献。)

现在 ZipFile.open() 方法的 mode 参数可接受 "x" 来请求独占式的创建。 (由 Serhiy Storchaka 在 bpo-21717 中贡献。)

其他模块级更改

现在 mmap, ossaudiodev, socket, sslcodecs 模块中的许多函数都接受可写的 字节型对象。 (由 Serhiy Storchaka 在 bpo-23001 中贡献。)

性能优化

os.walk() 函数在 POSIX 系统上可提速 3 至 5 倍,而在 Windows 上可提速 7 至 20 倍。 这是因为使用了新的 os.scandir() 函数,它可以暴露来自下层 readdirFindFirstFile/FindNextFile 系统调用的文件信息。 (由 Ben Hoyt 在 bpo-23605 中贡献并得到 Victor Stinner 的协助。)

对于大对象 bytes(int) (以零字节填充) 的构建速度更快且使用更少内存。 将使用 calloc() 而不是 malloc() 为这些对象分配内存。 (由 Victor Stinner 在 bpo-21233 中贡献。)

ipaddress 中的 IPv4NetworkIPv6Network 等操作获得了大幅度的加速,比如 subnets(), supernet(), summarize_address_range(), collapse_addresses()。 加速幅度从 3 到 15 倍不等。 (由 Antoine Pitrou, Michel Albert 和 Markus 在 bpo-21486, bpo-21487, bpo-20826, bpo-23266 中贡献。)

ipaddress 对象的封存操作获得了优化以产生显著减小的输出。 (由 Serhiy Storchaka 在 bpo-23133 中贡献。)

现在 io.BytesIO 上的许多操作可提速 50% 至 100%。 (由 Serhiy Storchaka 在 bpo-15381 以及 David Wilson 在 bpo-22003 中贡献。)

现在 marshal.dumps() 函数速度可提升:对于典型数据来说版本 3 和 4 为 65--85%,版本 0 至 2 为 20--25%,最佳场景下最多可达 5 倍。 (由 Serhiy Storchaka 在 bpo-20416bpo-23344 中贡献。)

现在 UTF-32 编码器可提速 3 至 7 倍。 (由 Serhiy Storchaka 在 bpo-15027 中贡献。)

现在正则表达式的解析可提速至多 10%。 (由 Serhiy Storchaka 在 bpo-19380 中贡献。).)

json.dumps() 函数已获优化使得设置 ensure_ascii=False 时与设置 ensure_ascii=True 时运行得一样快。 (由 Naoki Inada 在 bpo-23206 中贡献。)

PyObject_IsInstance()PyObject_IsSubclass() 函数在第二个参数以 type 作为其元类的常见情况下已获得加速。 (由 Georg Brandl 在 bpo-22540 中贡献。)

方法缓存操作已获少量改进,在某些基准测试中可产生至多 5% 的性能提升。 (由 Antoine Pitrou 在 bpo-22847 中贡献。)

现在来自 random 模块的对象在 64 位编译版上使用的内存将减少 50%。 (由 Serhiy Storchaka 在 bpo-23488 中贡献。)

property() getter 调用可提速 25%。 (由 Joe Jevnik 在 bpo-23910 中贡献。)

现在 fractions.Fraction 的实例化可提速至多 30%。 (由 Stefan Behnel 在 bpo-22464 中贡献。)

现在字符串方法 find(), rfind(), split(), partition()in 字符串运算符在搜索 1 个字符的子字符串时将显著提速。 (由 Serhiy Storchaka 在 bpo-23573 中贡献。)

构建和 C API 的改变

增加了 calloc 函数

(Victor Stinner 贡献于 bpo-21233.)

新的 encoding/decoding 帮助函数:

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

新增的 PyCodec_NameReplaceErrors() 函数可以将 unicode 编码错误替换为 \N{...} 转义符号。 (由 Serhiy Storchaka 在 bpo-19676 中贡献。)

新增的 PyErr_FormatV() 函数类似于 PyErr_Format(),但还接受一个 va_list 参数。 (由 Antoine Pitrou 在 bpo-18711 中贡献。)

新增 PyExc_RecursionError 异常。 (由 Georg Brandl 在 bpo-19235 中贡献。)

新增 PyModule_FromDefAndSpec(), PyModule_FromDefAndSpec2()PyModule_ExecDef() 函数,来自 PEP 489 -- 多阶段扩展模块初始化。 (由 Petr Viktorin 在 bpo-24268 中贡献。)

新增 PyNumber_MatrixMultiply()PyNumber_InPlaceMatrixMultiply() 函数用于执行矩阵乘法。 (由 Benjamin Peterson 在 bpo-21176 中贡献。 另请参阅 PEP 465 了解详情。)

现在 PyTypeObject.tp_finalize 槽位已成为稳定 ABI 的一部分。

Windows 构建现在需要 Microsoft Visual C++ 14.0,它是 Visual Studio 2015 的一部分。

现在扩展模块在某些平台上的文件名将包括平台信息标签(该标签是可选的,即使没有它 CPython 也会导入扩展,但是如果存在不匹配的标签,扩展将不会被加载):

  • 在 Linux 上,扩展模块文件名将以 .cpython-<major><minor>m-<architecture>-<os>.pyd 结束:

    • <major> 为 Python 主版本号;对于 Python 3.5 即为 3

    • <minor> 为 Python 次版本号;对于 Python 3.5 即为 5

    • <architecture> 为扩展模块构建在运行时所使用的硬件架构。 最常见的值是 i386 表示 32 位 Intel 平台或 x86_64 表示 64 位 Intel (和 AMD) 平台。

    • <os> 将始终为 linux-gnu,除非扩展构建是针对 64 位平台上的 32 位 ABI,在此情况下它将为 linux-gnu32 (而 <architecture> 将为 x86_64)。

  • 在 Windows 上,扩展模块文件名将以 <debug>.cp<major><minor>-<platform>.pyd 结束:

    • <major> 为 Python 主版本号;对于 Python 3.5 即为 3

    • <minor> 为 Python 次版本号;对于 Python 3.5 即为 5

    • <platform> 是扩展模块构建所针对的平台,可以为 win32 表示 Win32,win_amd64 表示 Win64,win_ia64 表示 Windows Itanium 64,win_arm 表示 ARM 版 Windows。

    • 如果以调试模式构建,则 <debug> 将为 _d,在其他情况下将为空白。

  • 在 OS X 平台上,扩展模块文件名现在将以 -darwin.so 结束。

  • 在所有其他平台上,扩展模块文件名与 Python 3.4 时一样。

弃用

新关键字

不建议将 asyncawait 用作变量、类、函数或模块的名称。 它们根据 PEP 492 在 Python 3.5 中被引入,并将在 Python 3.7 成为保留关键字。

已弃用的 Python 行为

在生成器内部引发 StopIteration 异常现在将静默生成一个 PendingDeprecationWarning,这将在 Python 3.6 中改为非静默的弃用警告并在 Python 3.7 中触发 RuntimeError。 请参阅 PEP 479: 修改生成器内部的 StopIteration 处理方式 了解详情。

不支持的操作系统

Windows XP 已不再被 Microsoft 所支持,因此根据 PEP 11,CPython 3.5 不再对该操作系统提供官方支持。

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

现在 formatter 模块状态已转为完全弃用并仍计划在 Python 3.6 中移除。

asyncio.async() 函数已被弃用并由 of ensure_future() 取代。

在过去 smtpd 模块总是会使用 utf-8 编解码器来解码电子邮件消息的 DATA 部分。 现在这可以通过传给 SMTPServer 的新关键字 decode_data 来控制。 默认值为 True,但该默认值已被弃用。 请将 decode_data 关键字指定为适当的值以避免弃用警告。

直接向 http.cookies.Morsel 对象的 key, valuecoded_value 赋值操作已弃用。 请改用 set()。 此外,set() 未写入文档的 LegalChars 形参也已弃用,现在将会被忽略。

将格式字符串作为关键字参数 format_string 传给 string.Formatter 类的 format() 方法的操作已被弃用。 (由 Serhiy Storchaka 在 bpo-23671 贡献。)

现在 platform.dist()platform.linux_distribution() 函数已被弃用。 各种 Linux 发行版使用太多不同的方式来描述自己,所以此功能将留给具体的包来实现。 (由 Vajrasky Kok 和 Berker Peksag 在 bpo-1322 中贡献。)

之前未写入文档的 inspect.Signaturefrom_functionfrom_builtin 方法已被弃用。 请改用新的 Signature.from_callable() 方法。 (由 Yury Selivanov 在 bpo-24248 中贡献。)

inspect.getargspec() 函数已被弃用并计划在 Python 3.6 中移除。 (请参阅 bpo-20438 了解详情。)

inspectgetfullargspec(), getcallargs()formatargspec() 函数已被弃用而应改用 inspect.signature() API。 (由 Yury Selivanov 在 bpo-20438 中贡献。)

在 Python 3.5.0 发布时 getargvalues()formatargvalues() 函数被误标记为已弃用。

在 str 模式中使用 re.LOCALE 旗标或 re.ASCII 的做法现在已被弃用。 (由 Serhiy Storchaka 在 bpo-22407 中贡献。)

在正则表达式模式和替换模式中使用不可识别的由 '\' 加一个 ASCII 字母组成的序列的做法现在会引发弃用警告并将在 Python 3.6 中被禁止。 (由 Serhiy Storchaka 在 bpo-23622 中贡献。)

现在 unittest.TestLoader.loadTestsFromModule() 方法未写入文档的非官方 use_load_tests 默认参数已被弃用并会被忽略。 (由 Robert Collins 和 Barry A. Warsaw 在 bpo-16662 中贡献。)

移除

API 与特性的移除

以下过时并在之前版本中弃用的 API 和特性现已被移除:

  • __version__ 属性已从 mail 包中被去除。 email 包的代码已经很久没有与 stdlib 分开发布了,而 __version__ 字符串在最近几次发布版中也没有被更新。

  • ftplib 模块中的内部 Netrc 类在 3.4 中被弃用,现在已被移除。 (由 Matt Chaput 在 bpo-6623 中贡献。)

  • .pyo 文件的概念已被移除。

  • 暂定的 asyncio 模块中的 JoinableQueue 类在 3.4.4 中被弃用,现在已被移除。 (由 A. Jesse Jiryu Davis 在 bpo-23464 中贡献。)

移植到Python 3.5

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

Python 行为的改变

  • 由于一个疏忽,之前的 Python 版本会错误地接受以下语法:

    f(1 for x in [1], *args)
    f(1 for x in [1], **kwargs)
    

    对于生成器表达式不是传给函数的唯一参数时必须放在圆括号内的情况,Python 3.5 现在会正确地引发 SyntaxError

Python API 的变化

  • PEP 475: 现在当系统调用被信号中断时如果 Python 信号处理器没有引发异常则会执行重试而不是引发 InterruptedError

  • 在 Python 3.5 之前,如果一个 datetime.time 对象是表示 UTC 时间的午夜则会被视为假值。 此行为被认为容易造成困惑和错误因而在 Python 3.5 中已被去除。 详情参见 bpo-13936

  • The ssl.SSLSocket.send() method now raises either ssl.SSLWantReadError or ssl.SSLWantWriteError on a non-blocking socket if the operation would block. Previously, it would return 0. (Contributed by Nikolaus Rath in bpo-20951.)

  • 现在生成器的 __name__ 属性是根据函数名设置的,而不是根据代码名设置的。 请使用 gen.gi_code.co_name 来获取代码名。 生成器还有一个新的 __qualname__ 属性,即限定名称,它现在用于生成器的表示形式 (repr(gen))。 (由 Victor Stinner 在 bpo-21205 中贡献。)

  • 已弃用的 "strict" 模式和 HTMLParser, HTMLParser.error()HTMLParserError 异常参数已被移除。 (由 Ezio Melotti 在 bpo-15114 中贡献。) 现在 HTMLParserconvert_charrefs 参数默认为 True。 (由 Berker Peksag 在 bpo-21047 中贡献。)

  • 虽然不是 API 的正式组成部分,但对于移植目的(例如:修复测试)来说需要注意之前 "'sometype' does not support the buffer protocol" 形式的错误消息现在将为 "a bytes-like object is required, not 'sometype'" 形式。 (由 Ezio Melotti 在 bpo-16518 中贡献。)

  • 在当前目录被设为已不存在的目录时将不再引发 FileNotFoundError 而是改为 find_spec() 返回 None 并且 不在 sys.path_importer_cache 中缓存 None,这与典型的场景存在区别 (bpo-22834)。

  • http.clienthttp.server 中的 HTTP 状态码和消息被重构为一个通用的 HTTPStatus 枚举。 http.clienthttp.server 中的值仍可被用于向下兼容性。 (由 Demian Brecht 在 bpo-21793 中贡献。)

  • 现在当一个导入加载器定义了 importlib.machinery.Loader.exec_module() 时它也应该定义 create_module() (现在会引发 DeprecationWarning,在 Python 3.6 中将引发错误)。 如果加载器是继承自 importlib.abc.Loader 那么就不需要做什么,在其他情况下只须定义 create_module() 来返回 None。 (由 Brett Cannon 在 bpo-23014 中贡献。)

  • re.split() 函数总是会忽略空的模式匹配,因此 "x*" 模式的效果与 "x+" 相同,而 "\b" 模式则没有效果。 现在当模式将匹配空字符串时 re.split() 会引发一个警告。 为保持兼容性,请使用绝不会匹配空字符串的模式 (例如使用 "x+" 而不是 "x*")。 只匹配空字符串的模式 (例如 "\b") 现在会引发一个错误。 (由 Serhiy Storchaka 在 bpo-22818 中贡献。)

  • http.cookies.Morsel 字典型接口已更为自洽:morsel 比较现在会将 keyvalue 都纳入考虑,copy() 现在将得到一个 Morsel 实例而不是 dict,而 update() 现在当更新字典中的任一个键无效时将引发一个异常。 此外,set() 中未写入文档的 LegalChars 形参已被弃用并且现在会被忽略。 (由 Demian Brecht 在 bpo-2211 中贡献。)

  • PEP 488 从 Python 中移除了``.pyo`` 文件并在 .pyc 文件名中引入可选的 opt- 标签。 importlib.util.cache_from_source() 增加了 optimization 形参以协助控制 opt- 标签。 为此,该函数的 debug_override 形参现在已被弃用。 .pyo 文件也已不再可以作为传给 Python 解释器的文件参数并且在单独分发(即不带源码的代码分发)时将不起作用。 由于在 Python 3.5 中字节码的魔术数字已被改变,即使在不考虑此 PEP 的情况下所有之前版本的 Python 的旧 .pyo 文件都已不可用。

  • 现在 socket 模块会在 linux 3.6 或更高版本上导出 CAN_RAW_FD_FRAMES 常量。

  • 根据 RFC 5280,现在 ssl.cert_time_to_seconds() 函数会将输入的时间解读为 UTC 而不是本地时间。 此外,其返回值必须为 int。 (由 Akira Li 在 bpo-19940 中贡献。)

  • 现在 pygettext.py 工具将为 POT-Creation-Date 标头中的时区使用标准的 +NNNN 格式。

  • 现在 smtplib 模块对于调试输出将使用 sys.stderr 而不是之前的模块级 stderr 变量。 如果你的(测试)程序依赖于对模块级变量打补丁来捕获调试输出,你将需要更新代码将其改为捕获 sys.stderr。

  • 当发现空字符串且索引完全超出范围时 str.startswith()str.endswith() 方法将不再返回 True。 (由 Serhiy Storchaka 在 bpo-24284 中贡献。)

  • 现在 inspect.getdoc() 将返回从基类继承的文档字符串。 如果继承的文档字符串可用就不需要再复制文档字符串。 要屏蔽继承的字符串,必须指定一个空字符串(否则将会填充文档)。 此项改变将影响 pydoc 模块和 help() 函数的输出。 (由 Serhiy Storchaka 在 bpo-15582 中贡献。)

  • 嵌套的 functools.partial() 调用现在已被展平。 如果你需要之前的行为,现在你可以为 functools.partial() 对象添加一个属性或者创建一个 functools.partial() 的子类。 (由 Alexander Belopolsky 在 bpo-7830 中贡献。)

C API 的变化

  • (非公开) PyMemoryViewObject 结构体中未写入文档的 format 成员已被移除。 所有依赖于 memoryobject.h 中相关部分的扩展都必须重新编译。

  • The PyMemAllocator structure was renamed to PyMemAllocatorEx and a new calloc field was added.

  • 移除了会泄漏引用的未写入文档的宏 PyObject_REPR()。请在 PyUnicode_FromFormat() 之类的函数中使用格式符 %R 来格式化对象的 repr()。 (由 Serhiy Storchaka 在 bpo-22453 中贡献。)

  • Because the lack of the __module__ attribute breaks pickling and introspection, a deprecation warning is now raised for builtin types without the __module__ attribute. This will be an AttributeError in the future. (Contributed by Serhiy Storchaka in bpo-20204.)

  • 作为 PEP 492 实现的一部分,PyTypeObjecttp_reserved 槽位被替换为 tp_as_async 槽位。 请参看 协程对象 了解相关的新类型、结构体和函数。

Python 3.5.4 的显著变化

新增 make regen-all 构建目标

为了简化交叉编译,并确保 CPython 能够可靠地编译而不需要已存在可用的 Python 版本,基于 autotools 的构建系统将不再尝试根据文件修改时间隐式地重新编译已生成的文件。

取而代之的是,新增了一个 make regen-all 命令以便在需要时强制重新生成这些文件(例如在基于预生成版本构建了 Python 的初始版本之后)。

还定义了其他一些更具选择性的重生成目标 —— 详情参见 Makefile.pre.in

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

Added in version 3.5.4.

移除了 make touch 构建目标

之前用于通过更新生成文件的修改时间来请求隐式的重新生成这些文件的 make touch 构建目标已被移除。

它已被新的 make regen-all 目标所替代。

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

在 3.5.4 版本发生变更.