- Python 3.5 有什么新变化
- 摘要 — 发布重点
- 新的特性
- PEP 492 - 使用 async 和 await 语法实现协程
- PEP 465 - 用于矩阵乘法的专用中缀运算符
- PEP 448 - 进一步的解包标准化
- PEP 461 - 针对 bytes 和 bytearray 的百分号格式化支持
- PEP 484 —— 类型提示
- PEP 471 - os.scandir() 函数 — 一个更好且更快的目录迭代器
- PEP 475: 重试返回 EINTR 失败码的系统调用
- PEP 479:更改生成器内部的 StopIteration 处理
- PEP 485:用于测试近似相等的函数
- PEP 486:让 Python 启动器识别虚拟环境
- PEP 488:去除 PYO 文件
- PEP 489:多阶段扩展模块初始化
- 其他语言特性修改
- 新增模块
- 改进的模块
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 [https://docs.python.org/3.5/whatsnew/changelog.html]。
参见
PEP 478 [https://peps.python.org/pep-0478/] - Python 3.5 发布计划
摘要 — 发布重点
新的语法特性:
新的库模块:
新的内置特性:
bytes % args
,bytearray % args
: PEP 461 — 为字节串和字节数组增加%
格式化。新增
bytes.hex()
,bytearray.hex()
和memoryview.hex()
方法。 (由 Arnon Yaari 在 bpo-9951 [https://bugs.python.org/issue?@action=redirect&bpo=9951] 中贡献。)memoryview
现在支持元组索引(包括多维度)。 (由 Antoine Pitrou 在 bpo-23632 [https://bugs.python.org/issue?@action=redirect&bpo=23632] 中贡献。)生成器具有一个新的
gi_yieldfrom
属性,它将返回yield from
表达式所迭代的对象。 (由 Benno Leslie 和 Yury Selivanov 在 bpo-24450 [https://bugs.python.org/issue?@action=redirect&bpo=24450] 中贡献。)现在当达到最大递归尝试时将引发新的
RecursionError
异常。 (由 Georg Brandl 在 bpo-19235 [https://bugs.python.org/issue?@action=redirect&bpo=19235] 中贡献。)
CPython 实现的改进:
当
LC_TYPE
语言区域为 POSIX 语言区域(即C
语言区域)时,sys.stdin
和sys.stdout
现在将使用surrogateescape
错误处理器,而不是strict
错误处理器。 (由 Victor Stinner 在 bpo-19977 [https://bugs.python.org/issue?@action=redirect&bpo=19977] 中贡献。).pyo
文件已不再被使用而是被替换为一个更灵活的方案即在.pyc
名称中显式地包括优化级别。 (参见 PEP 488 概览。)内置与扩展模块现在将经过多阶段的过程被初始化,这类似于 Python 模块的加载方式。 (参见 PEP 489 概览。)
标准库中的重大改进:
collections.OrderedDict
现在已 用 C 实现,这使它的速度快了 4 到 100 部。The
ssl
模块获得了 对内存 BIO 的支持,它使得 SSL 协议处理与网络 IO 实现了解耦。新的
os.scandir()
函数提供了对于目录遍历 更好和明显更快速的方式。functools.lru_cache()
已经大部分 用 C 重新实现,产生了更好的性能。新的
subprocess.run()
函数提供了一个 运行子进程的简便方式。
安全改进:
SSLv3 目前在整个标准库中被禁用。 它仍然可以通过手动实例化一个
ssl.SSLContext
来启用。 (请参阅 bpo-22638 [https://bugs.python.org/issue?@action=redirect&bpo=22638] 了解详情;此修改已向下移植到 CPython 3.4 和 2.7。)HTTP cookie 解析现在将更严格,以防止潜在的注入攻击。 (由 Antoine Pitrou 在 bpo-22796 [https://bugs.python.org/issue?@action=redirect&bpo=22796] 中贡献。)
Windows改进:
使用新的 Windows 安装器替代了旧版 MSI。 请参阅 在Windows上使用 Python 了解详情。
Windows 编译版现在使用 Microsoft Visual C++ 14.0,扩展模块也应当使用同一版本。
请继续阅读有关针对用户的改变的完整清单,包括许多其他较小的改进、CPython 优化、弃用以及潜在的移植问题。
新的特性
PEP 492 - 使用 async 和 await 语法实现协程
PEP 492 [https://peps.python.org/pep-0492/] 通过添加 可等待对象, 协程函数, 异步迭代 和 异步上下文管理器 极大地改善了 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 HTTP1.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 for
和 async with
都只能在通过 async def
声明的协程函数中使用。
协程函数应当在兼容的事件循环内部运行,例如 asyncio 循环。
备注
在 3.5.2 版本发生变更: 从 CPython 3.5.2 开始,__aiter__
可以直接返回 异步迭代器。 返回 awaitable 对象将会导致 PendingDeprecationWarning
。
详情参见文档的 异步迭代器 一节。
参见
- PEP 492 [https://peps.python.org/pep-0492/] — 使用 async 和 await 语法实现协程
- PEP 由 Yury Selivanov 撰写并实现
PEP 465 - 用于矩阵乘法的专用中缀运算符
PEP 465 [https://peps.python.org/pep-0465/] 增加了用于矩阵乘法的 @
中缀运算符。 目前,还没有内置的 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 [https://peps.python.org/pep-0465/] — 用于矩阵乘法的专用中缀运算符
- PEP 由 Nathaniel J. Smith 撰写,由 Benjamin Peterson 实现。
PEP 448 - 进一步的解包标准化
PEP 448 [https://peps.python.org/pep-0448/] 扩展了 *
可迭代对象解包操作符和 **
字典解包操作符的允许使用范围。 现在将可以在 函数调用 中使用任意数量的解包操作:
- >>> 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 [https://peps.python.org/pep-0448/] — 进一步的解包标准化
- PEP 由 Joshua Landau 撰写 ,由 Neil Girdhar,Thomas Wouters 和 Joshua Landau 实现。
PEP 461 - 针对 bytes 和 bytearray 的百分号格式化支持
PEP 461 [https://peps.python.org/pep-0461/] 增加了 %
插值运算符 对 bytes
和 bytearray
的支持。
虽然插值通常被认为是一种字符串操作,但在某些情况下针对 bytes
或 bytearrays
的插值操作也是有意义,而弥补这种功能缺失所需的工作可能会影响代码的整体可读性。 在处理通常会混合二进制和 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 [https://peps.python.org/pep-0461/] — 为 bytes 和 bytearray 添加 % 格式化
- PEP 由 Ethan Furman 撰写 ,由 Neil Schemenauer 和 Ethan Furman 实现。
PEP 484 —— 类型提示
函数标注语法自 3.0 版起即已成为 Python 的特性 ( PEP 3107 [https://peps.python.org/pep-3107/]),标注的语义尚未得到定义。
经验表明大多数函数标注的使用都是为了向函数形参和返回值提供类型提示。 很显然如果标准库可以包括用于类型标注的基本定义和工具,对 Python 用户来说将大有裨益。
PEP 484 [https://peps.python.org/pep-0484/] 引入了一个 暂定模块 来提供这些标准定义和工具,以及针对标注不可用的场合的一些惯例。
例如,以下是一个在标注中声明了参数和返回值类型的简单函数:
- def greeting(name: str) -> str:
- return 'Hello ' + name
虽然这些标注可在运行时通过常用的 __annotations__
属性来访问,但是 不会在运行时进行自动类型检查。 作为替代,应该会为按需执行源代码分析提供一个单独的离线版类型检查器 (例如 mypy [https://mypy-lang.org])。
类型系统支持合并、泛型类型以及名为 Any
的能够适用于所有类型(即作为赋值的来源和目标)的特殊类型。
参见
typing
模块文档- PEP 484 [https://peps.python.org/pep-0484/] —— 类型提示
- PEP 由 Guido van Rossum,Jukka Lehtosalo 和 Łukasz Langa 撰写;由 Guido van Rossum 实现。
- PEP 483 [https://peps.python.org/pep-0483/] — 类型提示理论
- PEP 由 Yury Selivanov 撰写
PEP 471 - os.scandir() 函数 — 一个更好且更快的目录迭代器
PEP 471 [https://peps.python.org/pep-0471/] 向标准库添加了一个新的目录迭代函数 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 [https://peps.python.org/pep-0471/] — os.scandir() 函数 — 一个更好且更快的目录迭代器
- PEP 由 Ben Hoyt 在 Victor Stinner 的帮助下撰写并实现
PEP 475: 重试返回 EINTR 失败码的系统调用
当一个正在等待 I/O 的系统调用被信号所中断时将会返回一个 errno.EINTR
错误码。 在之前版本中,Python 会在这种情况下引发 InterruptedError
。 这意味着在编写 Python 应用程序时,开发者有两种选择:
忽略
InterruptedError
。处理
InterruptedError
并在每个调用位置尝试重新启动被中断的系统调用。
第一个选项会使应用程序中途出错。 第二个选项添加了大量的额外处理使得代码几乎不可读。 比较:
- print("Hello World")
和:
- while True:
- try:
- print("Hello World")
- break
- except InterruptedError:
- continue
PEP 475 [https://peps.python.org/pep-0475/] 实现了在 EINTR
时自动重试系统调用。 这移除了大部分场合下在用户代码中处理 EINTR
或 InterruptedError
的负担,并使得 Python 程序,包括标准库的程序更为健壮。 请注意只有在信号处理器未引发异常时系统调用才会被重试。
以下是现在当被信号中断时会被重试的函数的列表:
faulthandler
模块的功能os
函数:fchdir()
,fchmod()
,fchown()
,fdatasync()
,fstat()
,fstatvfs()
,fsync()
,ftruncate()
,mkfifo()
,mknod()
,open()
,posix_fadvise()
,posix_fallocate()
,pread()
,pwrite()
,read()
,readv()
,sendfile()
,wait3()
,wait4()
,wait()
,waitid()
,waitpid()
,write()
,writev()
;特殊情况:
os.close()
和os.dup2()
现在会忽略EINTR
错误;系统调用将不被重试(请参阅 PEP 了解相关的理由);select
函数:devpoll.poll()
,epoll.poll()
,kqueue.control()
,poll.poll()
,select()
;socket
类的方法:accept()
,connect()
(除了非阻塞套接字),recv()
,recvfrom()
,recvmsg()
,send()
,sendall()
,sendmsg()
,sendto()
;
参见
- PEP 475 [https://peps.python.org/pep-0475/] — 重试返回 EINTR 失败码的系统调用
- PEP 和具体实现由 Charles-François Natali 和 Victor Stinner 撰写,并获得 Antoine Pitrou 的协助(同为法国人)。
PEP 479:更改生成器内部的 StopIteration 处理
生成器与 StopIteration
的交互在 Python 3.4 及更早版本中有时会令人惊讶,并可能隐藏难以觉察的程序错误。 在之前版本中,一个生成器函数内部意外引发的 StopIteration
会被驱动该生成器的循环构造解读为迭代的结束。
PEP 479 [https://peps.python.org/pep-0479/] 更改了生成器的行为:当一个 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
- 上述异常是导致以下异常的直接原因:
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- RuntimeError: generator raised StopIteration
如果未执行 __future__
导入,当在生成器内部引发 StopIteration
异常时将导致 PendingDeprecationWarning
被引发。
参见
- PEP 479 [https://peps.python.org/pep-0479/] — 更改生成器内部的 StopIteration 处理
- PEP 由 Chris Angelico 和 Guido van Rossum 撰写,由 Chris Angelico,Yury Selivanov 和 Nick Coghlan 实现。
PEP 485:用于测试近似相等的函数
PEP 485 [https://peps.python.org/pep-0485/] 增加了 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 [https://peps.python.org/pep-0485/] —— 用于测试近似相等的函数
- PEP 由 Christopher Barker 撰写,由 Chris Barker 和 Tal Einat 实现。
PEP 486:让 Python 启动器识别虚拟环境
PEP 486 [https://peps.python.org/pep-0486/] 让 Windows 版启动器 (参见 PEP 397 [https://peps.python.org/pep-0397/]) 能够识别激活的虚拟环境。 当要使用默认解释器并且设置了 VIRTUAL_ENV
环境变量时,将使用虚拟环境中的解释器。
参见
- PEP 486 [https://peps.python.org/pep-0486/] — 让 Python 启动器识别虚拟环境
- PEP 由 Paul Moore 撰写并实现
PEP 488:去除 PYO 文件
PEP 488 [https://peps.python.org/pep-0488/] 取消了 .pyo
文件的概念。 这意味着 .pyc
文件将同时代表未优化和已优化的字节码。 为了防止经常需要重新生成字节码文件,现在 .pyc
文件可以在其名称中设置可选的 opt-
标签来表示已优化字节码。 该设置的附带效果是当以 -O
和 -OO
运行时将不会有字节码文件名冲突。 其结果是,使用 -O
和 -OO
生成的字节码现在可以同时存在。 importlib.util.cache_from_source()
专门针对此项变化更新了 API。
参见
- PEP 488 [https://peps.python.org/pep-0488/] — 去除 PYO 文件
- PEP 由 Brett Cannon 撰写并实现。
PEP 489:多阶段扩展模块初始化
PEP 489 [https://peps.python.org/pep-0489/] 更新了扩展模块初始化操作以便利用 Python 3.4 中通过 PEP 451 [https://peps.python.org/pep-0451/] 引入的两步模块加载机制的优势。
这一变化让选择使用新机制的扩展模块的导入语义与 Python 源代码和字节码模块的更为接近,包括可以使用任何有效标识符作为模块名称,而不是仅限于 ASCII。
参见
- PEP 489 [https://peps.python.org/pep-0489/] — 多阶段扩展模块初始化
- PEP 由 Petr Viktorin , Stefan Behnel 和 Nick Coghlan 撰写,由 Petr Viktorin 实现。
其他语言特性修改
对Python 语言核心进行的小改动:
增加了
"namereplace"
错误处理器。"backslashreplace"
错误处理器现在可用于解码和转译。 (由 Serhiy Storchaka 在 bpo-19676 [https://bugs.python.org/issue?@action=redirect&bpo=19676] 和 bpo-22286 [https://bugs.python.org/issue?@action=redirect&bpo=22286] 中贡献。)现在
-b
选项会影响bytes
与int
的比较。 (由 Serhiy Storchaka 在 bpo-23681 [https://bugs.python.org/issue?@action=redirect&bpo=23681] 中贡献。)新增 Kazakh
kz1048
和 Tajikkoi8_t
编解码器。 (由 Serhiy Storchaka 在 bpo-22682 [https://bugs.python.org/issue?@action=redirect&bpo=22682] 和 bpo-22681 [https://bugs.python.org/issue?@action=redirect&bpo=22681] 中贡献。)特征属性文档字符串现在将是可写的。 这对于
collections.namedtuple()
文档字符串特别适用。 (由 Berker Peksag 在 bpo-24064 [https://bugs.python.org/issue?@action=redirect&bpo=24064] 中贡献。)涉及相对导入的环形导入现在已受到支持。 (由 Brett Cannon 和 Antoine Pitrou 在 bpo-17636 [https://bugs.python.org/issue?@action=redirect&bpo=17636] 中贡献。)
新增模块
typing
新增的 typing
暂定 模块提供了对函数类型标注的标准定义和工具。 详情参见 类型提示。
zipapp
新增的 zipapp
模块(在 PEP 441 [https://peps.python.org/pep-0441/] 中描述)提供了用于创建可执行 Python Zip 应用程序的 API 和命令行工具,它是根据 bpo-1739468 [https://bugs.python.org/issue?@action=redirect&bpo=1739468] 在 Python 2.6 中引入的,但在当时和之后都没有足够的推广。
使用这个新模块,想要打包你的应用程序只需简单地将所有文件,包括一个 __main__.py
文件放到一个目录 myapp
中并运行:
- $ python -m zipapp myapp
- $ python myapp.pyz
该模块的实现由 Paul Moore 在 bpo-23491 [https://bugs.python.org/issue?@action=redirect&bpo=23491] 中贡献。
参见
PEP 441 [https://peps.python.org/pep-0441/] — 改进 Python ZIP 应用程序支持
改进的模块
argparse
现在 ArgumentParser
类允许通过将 allow_abbrev 设为 False
来禁用长选项的 缩写用法。 (由 Jonathan Paugh, Steven Bethard, paul j3 和 Daniel Eriksson 在 bpo-14910 [https://bugs.python.org/issue?@action=redirect&bpo=14910] 中贡献。)
asyncio
由于 asyncio
模块处于 暂定状态,在 Python 3.5 中引入的所有改变都已被向下移植到 Python 3.4.x。
自 Python 3.4.0 开始 asyncio
模块中的重要变化:
新增的调试 API:
loop.set_debug()
和loop.get_debug()
方法。 (由 Victor Stinner 贡献。)现在 proactor 事件循环已支持 SSL。 (由 Antoine Pitrou 和 Victor Stinner 在 bpo-22560 [https://bugs.python.org/issue?@action=redirect&bpo=22560] 中贡献。)
新增的
loop.is_closed()
方法可检测事件循环是否已关闭。 (由 Victor Stinner 在 bpo-21326 [https://bugs.python.org/issue?@action=redirect&bpo=21326] 中贡献。).)新增的
loop.create_task()
用来方便地新建一个Task
并将其排入协程的计划任务。create_task
方法还可供所有将协程包装为任务的 asyncio 函数使用,例如asyncio.wait()
,asyncio.gather()
等。 (由 Victor Stinner 贡献。)新增的
transport.get_write_buffer_limits()
方法用于查询流程控制的 高 与 低 水位限制。 (由 Victor Stinner 贡献。)async()
函数已被弃用并由ensure_future()
取代。 (由 Yury Selivanov 贡献。)新增
loop.set_task_factory()
和loop.get_task_factory()
方法用于自定义供loop.create_task()
方法使用的任务工厂。 (由 Yury Selivanov 贡献。)新增
Queue.join()
和Queue.task_done()
队列方法。 (由 Victor Stinner 贡献。)移除了
JoinableQueue
类,建议改用asyncio.Queue
类。 (由 Victor Stinner 贡献。)
3.5.1 中的更新:
ensure_future()
函数以及所有用到它的函数,比如loop.run_until_complete()
,现在将接受所有种类的 可等待对象。 (由 Yury Selivanov 贡献。)新增
run_coroutine_threadsafe()
函数用于从其他线程向事件循环提交协程。(由 Vincent Michel 贡献。)新增
Transport.is_closing()
方法用于检查传输是否正在关闭或已经关闭。 (由 Yury Selivanov 贡献。)loop.create_server()
方法现在可以接受一个主机列表。 (由 Yann Sionneau 贡献。)
3.5.2 中的更新:
新增
loop.create_future()
方法用来创建 Future 对象。 这允许替代性的事件循环实现,比如 uvloop [https://github.com/MagicStack/uvloop],以提供更快速的asyncio.Future
实现。 (由 Yury Selivanov 贡献。)新增
loop.get_exception_handler()
方法用于获取当前异常处理器。 (由 Yury Selivanov 贡献。)新增
StreamReader.readuntil()
方法用于从流读取数据直到出现作为分隔符的字节序列。 (由 Mark Korenberg 贡献。)loop.create_connection()
和loop.create_server()
方法已获得优化以避免当地址已被解析时调用系统的getaddrinfo
函数。 (由 A. Jesse Jiryu Davis 贡献。)loop.sock_connect(sock, address)
不再要求在其被调用之前已解析 address。 (由 A. Jesse Jiryu Davis 贡献。)
bz2
现在 BZ2Decompressor.decompress
方法接受可选的 max_length 参数用来限制解压缩数据的大小上限。 (由 Nikolaus Rath 在 bpo-15955 [https://bugs.python.org/issue?@action=redirect&bpo=15955] 中贡献。)
cgi
现在 FieldStorage
类已支持 context manager 协议。 (由 Berker Peksag 在 bpo-20289 [https://bugs.python.org/issue?@action=redirect&bpo=20289] 中贡献。)
cmath
新增函数 isclose()
提供了一种测试近似相等的方式。 (由 Chris Barker 和 Tal Einat 在 bpo-24270 [https://bugs.python.org/issue?@action=redirect&bpo=24270] 中贡献。)
code
现在 InteractiveInterpreter.showtraceback()
方法将打印完整的回溯链,就像在交互模式解释器中一样。 (由 Claudiu Popa 在 bpo-17442 [https://bugs.python.org/issue?@action=redirect&bpo=17442] 中贡献。)
collections
现在 OrderedDict
类使用 C 来实现,令其可提速 4 至 100 倍。 (由 Eric Snow 在 bpo-16991 [https://bugs.python.org/issue?@action=redirect&bpo=16991] 中贡献。)
OrderedDict.items()
, OrderedDict.keys()
, OrderedDict.values()
等视图现在支持 reversed()
迭代。 (由 Serhiy Storchaka 在 bpo-19505 [https://bugs.python.org/issue?@action=redirect&bpo=19505] 中贡献。)
deque
类现在定义了 index()
, insert()
和 copy()
,并且支持 +
和 *
运算符。 这允许 deque 被识别为 MutableSequence
并提升其替代列表的能力。 (由 Raymond Hettinger 在 bpo-23704 [https://bugs.python.org/issue?@action=redirect&bpo=23704] 中贡献。)
由 namedtuple()
产生的文档字符串现在可以被更新:
- Point = namedtuple('Point', ['x', 'y'])
- Point.__doc__ += ': Cartesian coordinate'
- Point.x.__doc__ = 'abscissa'
- Point.y.__doc__ = 'ordinate'
(由 Berker Peksag 在 bpo-24064 [https://bugs.python.org/issue?@action=redirect&bpo=24064] 中贡献。)
现在 UserString
类已实现 __getnewargs__()
, __rmod__()
, casefold()
, format_map()
, isprintable()
和 maketrans()
类以与对应的 str
方法相匹配。 (由 Joe Jevnik 在 bpo-22189 [https://bugs.python.org/issue?@action=redirect&bpo=22189] 中贡献。)
collections.abc
现在 Sequence.index()
方法接受 start 和 stop 参数以与对应的 tuple
, list
等的方法相匹配。 (由 Devin Jeanpierre 在 bpo-23086 [https://bugs.python.org/issue?@action=redirect&bpo=23086] 中贡献。)
新增 Generator
抽象基类。 (由 Stefan Behnel 在 bpo-24018 [https://bugs.python.org/issue?@action=redirect&bpo=24018] 中贡献。)
新增 Awaitable
, Coroutine
, AsyncIterator
和 AsyncIterable
抽象基类。 (由 Yury Selivanov 在 bpo-24184 [https://bugs.python.org/issue?@action=redirect&bpo=24184] 中贡献。)
对于更早的 Python 版本,这些新 ABC 的向下移植版本包含在外部的 PyPI 软件包 [https://pypi.org/project/backports_abc/] 之中。
compileall
新增 compileall
选项 -j N
,允许同时运行 N 个工作进程来执行并行的字节码编译。 compile_dir()
函数增加了相应的 workers
形参。 (由 Claudiu Popa 在 bpo-16104 [https://bugs.python.org/issue?@action=redirect&bpo=16104] 中贡献。)
另一个新选项 -r
,允许控制最大的子目录递归层级。 (由 Claudiu Popa 在 bpo-19628 [https://bugs.python.org/issue?@action=redirect&bpo=19628] 中贡献。)
现在可以多次指定 -q
命令行选项,在此情况下,所有输出包括错误都将被抑制。 在 compile_dir()
, compile_file()
和 compile_path()
中相应的 quiet
形参现在可接受一个整数值来指明输出抑制的级别。 (由 Thomas Kluyver 在 bpo-21338 [https://bugs.python.org/issue?@action=redirect&bpo=21338] 中贡献。)
concurrent.futures
现在 Executor.map()
方法接受一个 chunksize 参数以允许在使用 ProcessPoolExecutor()
设置任务批次来提升运行效率。 (由 Dan O'Reilly 在 bpo-11271 [https://bugs.python.org/issue?@action=redirect&bpo=11271] 中贡献。)
现在 ThreadPoolExecutor
构造器中的工作线程数量是可选的。 默认值为 CPU 数量的 5 倍。 (由 Claudiu Popa 在 bpo-21527 [https://bugs.python.org/issue?@action=redirect&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 [https://bugs.python.org/issue?@action=redirect&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 [https://bugs.python.org/issue?@action=redirect&bpo=22389] 中贡献。)
csv
现在 writerow()
方法可支持任意可迭代对象,而不仅是序列。 (由 Serhiy Storchaka 在 bpo-23171 [https://bugs.python.org/issue?@action=redirect&bpo=23171] 中贡献。)
curses
新增的 update_lines_cols()
函数可更新 LINES
和 COLS
模块变量。 这适用于检测手册页屏幕的大小变化。 (由 Arnon Yaari 在 bpo-4254 [https://bugs.python.org/issue?@action=redirect&bpo=4254] 中贡献。)
dbm
当设置旗标值为 "n"
时 dumb.open
将总是创建新的数据库。 (由 Claudiu Popa 在 bpo-18039 [https://bugs.python.org/issue?@action=redirect&bpo=18039] 中贡献。)
difflib
由 HtmlDiff.make_file()
生成的 HTML 文档的字符集现在可通过使用新增的 charset 仅限关键字参数来自定义。 HTML 文档的默认字符集已从 "ISO-8859-1"
改为 "utf-8"
。 (由 Berker Peksag 在 bpo-2052 [https://bugs.python.org/issue?@action=redirect&bpo=2052] 中贡献。)
现在 diff_bytes()
函数可能比较字节串的列表。 这修复了一个来自 Python 2 遗留总是。 (由 Terry J. Reedy 和 Greg Ward 在 bpo-17445 [https://bugs.python.org/issue?@action=redirect&bpo=17445] 中贡献。)
distutils
现在 build
和 build_ext
命令都接受一个 -j
选项以启用扩展模块的并行编译。 (由 Antoine Pitrou 在 bpo-5309 [https://bugs.python.org/issue?@action=redirect&bpo=5309] 中贡献。)
现在 distutils
模块支持 xz
压缩,并可通过将 xztar
作为传给 bdist --format
的参数来启用。 (由 Serhiy Storchaka 在 bpo-16314 [https://bugs.python.org/issue?@action=redirect&bpo=16314] 中贡献。)
doctest
如果 module 不包含任何文档字符串则 DocTestSuite()
函数将返回一个空的 unittest.TestSuite
,而不是引发 ValueError
。 (由 Glenn Jones 在 bpo-15916 [https://bugs.python.org/issue?@action=redirect&bpo=15916] 中贡献。)
新增的策略选项 Policy.mangle_from_
可控制生成器是否要为电子邮件消息体中以controls whether or not lines that start with "From "
打头的行添加 ">"
字符前缀。 默认 compat32
为 True
而所有其他策略均为 False
。 (由 Milan Oberkirch 在 bpo-20098 [https://bugs.python.org/issue?@action=redirect&bpo=20098] 中贡献。)
新增的 Message.get_content_disposition()
方法可提供对 Content-Disposition 标头规范值的便捷访问。 (由 Abhilash Raj 在 bpo-21083 [https://bugs.python.org/issue?@action=redirect&bpo=21083] 中贡献。)
新增的策略选项 EmailPolicy.utf8
可被设为 True
以使用 UTF-8 字符集而不是使用已编码的字来编码电子邮件标头。 这将允许根据 RFC 6532 [https://datatracker.ietf.org/doc/html/rfc6532.html] 来格式化 Messages
并配合支持 RFC 6531 [https://datatracker.ietf.org/doc/html/rfc6531.html] SMTPUTF8
扩展的 SMTP 服务器使用。 (由 R. David Murray 在 bpo-24211 [https://bugs.python.org/issue?@action=redirect&bpo=24211] 中贡献。)
现在 mime.text.MIMEText
构造器可接受一个 charset.Charset
实例。 (由 Claude Paroz 和 Berker Peksag 在 bpo-16324 [https://bugs.python.org/issue?@action=redirect&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 [https://bugs.python.org/issue?@action=redirect&bpo=21706] 中贡献。)
faulthandler
现在 enable()
, register()
, dump_traceback()
和 dump_traceback_later()
函数除了接受文件型对象以外也接受文件描述符。 (由 Wei Wu 在 bpo-23566 [https://bugs.python.org/issue?@action=redirect&bpo=23566] 中贡献。)
functools
现在大部分 lru_cache()
机制已使用 C 实现,使其速度显著提升。 (由 Matt Joiner, Alexey Kachayev 和 Serhiy Storchaka 在 bpo-14373 [https://bugs.python.org/issue?@action=redirect&bpo=14373] 中贡献。)
glob
现在 iglob()
和 glob()
函数支持通过使用 "**"
模式在子目录中递归搜索。 (由 Serhiy Storchaka 在 bpo-13968 [https://bugs.python.org/issue?@action=redirect&bpo=13968] 中贡献。)
gzip
现在 GzipFile
构造器的 mode 参数可接受 "x"
来请求独占式的创建。 (由 Tim Heaney 在 bpo-19222 [https://bugs.python.org/issue?@action=redirect&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 [https://bugs.python.org/issue?@action=redirect&bpo=13742] 中贡献。)
http
新增的 HTTPStatus
枚举定义了一组 HTTP 状态码、英文短说明和长描述。 (由 Demian Brecht 在 bpo-21793 [https://bugs.python.org/issue?@action=redirect&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 [https://bugs.python.org/issue?@action=redirect&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 [https://bugs.python.org/issue?@action=redirect&bpo=4972] 中贡献。)
现在 imaplib
模块已通过 IMAP4.enable()
方法支持 RFC 5161 [https://datatracker.ietf.org/doc/html/rfc5161.html] (ENABLE 扩展) 和 RFC 6855 [https://datatracker.ietf.org/doc/html/rfc6855.html] (UTF-8 支持)。 新增的 IMAP4.utf8_enabled
属性可跟踪 RFC 6855 [https://datatracker.ietf.org/doc/html/rfc6855.html] 支持是否被启用。 (由 Milan Oberkirch, R. David Murray 和 Maciej Szulik 在 bpo-21800 [https://bugs.python.org/issue?@action=redirect&bpo=21800] 中贡献。)
现在 imaplib
模块会自动使用 UTF-8 自动编码非 ASCII 字符串的用户名和密码,如 RFC 所建议的那样。 (由 Milan Oberkirch 在 bpo-21800 [https://bugs.python.org/issue?@action=redirect&bpo=21800] 中贡献。)
imghdr
现在 what()
函数可识别 OpenEXR [https://www.openexr.com] 格式(由 Martin Vignali 和 Claudiu Popa 在 bpo-20295 [https://bugs.python.org/issue?@action=redirect&bpo=20295] 中贡献),以及 WebP [https://en.wikipedia.org/wiki/WebP] 格式(由 Fabrice Aneche 和 Claudiu Popa 在 bpo-20197 [https://bugs.python.org/issue?@action=redirect&bpo=20197] 中贡献。)
importlib
util.LazyLoader
类允许在对启动时间敏感的应用程序中使用模块的惰性加载。 (由 Brett Cannon 在 bpo-17621 [https://bugs.python.org/issue?@action=redirect&bpo=17621] 中贡献。)
现在 abc.InspectLoader.source_to_code()
方法属于静态方法。 这样将可更方便地通过运行 exec(code, module.__dict__)
基于字符串编译的代码来初始化模块。 (由 Brett Cannon 在 bpo-21156 [https://bugs.python.org/issue?@action=redirect&bpo=21156] 中贡献。)
新增的 util.module_from_spec()
函数现在是创建新模块的首先方式。 相比直接创建 types.ModuleType
实例,这个新函数将基于传入的规格说明对象设置各种导入控制的属性。 (由 Brett Cannon 在 bpo-20383 [https://bugs.python.org/issue?@action=redirect&bpo=20383] 中贡献。)
inspect
现在 Signature
和 Parameter
类都是可封存和可哈希的对象。 (由 Yury Selivanov 在 bpo-20726 [https://bugs.python.org/issue?@action=redirect&bpo=20726] 和 bpo-20334 [https://bugs.python.org/issue?@action=redirect&bpo=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 [https://bugs.python.org/issue?@action=redirect&bpo=24190] 中贡献。)
新增的类方法 Signature.from_callable()
使得 Signature
的子类化更为容易。 (由 Yury Selivanov 和 Eric Snow 在 bpo-17373 [https://bugs.python.org/issue?@action=redirect&bpo=17373] 中贡献。)
现在 signature()
函数接受 followwrapped 可选关键字参数,当其设为 False
时,将禁用 \
_wrapped__
链接的自动跟随。 (由 Yury Selivanov 在 bpo-20691 [https://bugs.python.org/issue?@action=redirect&bpo=20691] 中贡献。)
新增了一组用于检查 协程函数 和 协程对象 的函数: iscoroutine()
, iscoroutinefunction()
, isawaitable()
, getcoroutinelocals()
和 getcoroutinestate()
。 (由 Yury Selivanov 在 bpo-24017 [https://bugs.python.org/issue?@action=redirect&bpo=24017] 和 bpo-24400 [https://bugs.python.org/issue?@action=redirect&bpo=24400] 中贡献。)
现在 stack()
, trace()
, getouterframes()
和 getinnerframes()
函数将返回具名元组的列表。 (由 Daniel Shahaf 在 bpo-16808 [https://bugs.python.org/issue?@action=redirect&bpo=16808] 中贡献。)
io
新增 BufferedIOBase.readinto1()
方法,该方法会使用至少一次对下层原始流的调用 RawIOBase.read()
或 RawIOBase.readinto()
方法。 (由 Nikolaus Rath 在 bpo-20578 [https://bugs.python.org/issue?@action=redirect&bpo=20578] 中贡献。)
ipaddress
现在 IPv4Network
和 IPv6Network
类均接受一个 (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 [https://bugs.python.org/issue?@action=redirect&bpo=16531] 中贡献。)
新增 IPv4Network
和 IPv6Network
类的 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 [https://bugs.python.org/issue?@action=redirect&bpo=20480] 中贡献。)
json
现在 json.tool
命令行接口会保留输入中传入的 JSON 对象中键的顺序。 新的 --sort-keys
选项可用于按字母顺序对键进行排序。 (由 Berker Peksag 在 bpo-21650 [https://bugs.python.org/issue?@action=redirect&bpo=21650] 中贡献。)
现在 JSON 解码器会引发 JSONDecodeError
而不是 ValueError
以提供有关错误的更好的上下文信息。 (由 Serhiy Storchaka 在 bpo-19361 [https://bugs.python.org/issue?@action=redirect&bpo=19361] 中贡献。)
linecache
新增的 lazycache()
函数可用于捕获非基于文件的模块 的信息以允许在此后通过 getline()
获取其行数据。 这样就可以避免在实际需要某一行之前执行 I/O 操作,从而不需要无限期地持有模块 globals。 (由 Robert Collins 在 bpo-17911 [https://bugs.python.org/issue?@action=redirect&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 [https://bugs.python.org/issue?@action=redirect&bpo=13918] 中贡献。)