Python 3.6 中的新增功能¶
- 编辑:
Elvis Pranskevichus <elvis@magic.io>, Yury Selivanov <yury@magic.io>
本文解释了 Python 3.6 相较于 3.5 的新功能。Python 3.6 于 2016 年 12 月 23 日发布。有关完整的更改列表,请参阅 更新日志。
参见
PEP 494 - Python 3.6 发布时间表
摘要 – 发布亮点¶
新语法功能
新库模块
CPython 实现改进
dict 类型已重新实现,以使用基于 Raymond Hettinger 的提案 的“更紧凑表示”,类似于 PyPy dict 实现。这使得字典比 Python 3.5 减少了 20% 到 25% 的内存使用。
使用 新协议 简化了类创建的自定义。
类属性的定义顺序 现在得到保留。
**kwargs
中元素的顺序现在 对应于 关键字参数传递给函数的顺序。已添加 DTrace 和 SystemTap 探测支持。
新的 PYTHONMALLOC 环境变量现在可用于调试解释器内存分配和访问错误。
标准库的重大改进
asyncio
模块获得了新功能、显著的可用性和性能改进,以及大量的 bug 修复。从 Python 3.6 开始,asyncio
模块不再是临时性的,其 API 被认为是稳定的。tracemalloc
模块已进行了重大修改,现在用于为ResourceWarning
提供更好的输出,并为内存分配错误提供更好的诊断。有关更多信息,请参阅 PYTHONMALLOC 部分。
安全改进
已添加新的
secrets
模块,以简化加密强度伪随机数的生成,适用于管理账户认证、令牌等密钥。在 Linux 上,
os.urandom()
现在会阻塞,直到系统 urandom 熵池初始化,以提高安全性。有关理由,请参阅 PEP 524。ssl
模块的默认设置和功能集已得到改进。hashlib
模块获得了对 BLAKE2、SHA-3 和 SHAKE 哈希算法以及scrypt()
密钥派生函数的支持。
Windows 改进
py.exe
启动器在交互式使用时,当用户未指定版本(通过命令行参数或配置文件)时,不再优先选择 Python 2 而不是 Python 3。shebang 行的处理保持不变 - 在这种情况下,“python”指的是 Python 2。python.exe
和pythonw.exe
已被标记为支持长路径,这意味着 260 字符的路径限制可能不再适用。有关详细信息,请参阅 删除 MAX_PATH 限制。可以添加
._pth
文件以强制隔离模式并完全指定所有搜索路径,以避免注册表和环境查找。有关更多信息,请参阅 文档。python36.zip
文件现在可用作推断PYTHONHOME
的标志。有关更多信息,请参阅 文档。
新功能¶
PEP 498: 格式化字符串字面量¶
PEP 498 引入了一种新型字符串字面量:f-strings,或 格式化字符串字面量。
格式化字符串字面量以 'f'
为前缀,类似于 str.format()
接受的格式字符串。它们包含由花括号包围的替换字段。替换字段是表达式,在运行时求值,然后使用 format()
协议进行格式化
>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # nested fields
'result: 12.35'
PEP 526: 变量注释语法¶
PEP 484 引入了函数参数类型注释(即类型提示)的标准。本 PEP 为 Python 添加了用于注释变量(包括类变量和实例变量)类型的语法
primes: List[int] = []
captain: str # Note: no initial value!
class Starship:
stats: Dict[str, int] = {}
与函数注释一样,Python 解释器不会为变量注释附加任何特定含义,而只是将它们存储在类或模块的 __annotations__
属性中。
与静态类型语言中的变量声明相反,注释语法的目标是提供一种简单的方式,通过抽象语法树和 __annotations__
属性为第三方工具和库指定结构化类型元数据。
PEP 515: 数字字面量中的下划线¶
PEP 515 增加了在数字字面量中使用下划线以提高可读性的能力。例如
>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295
允许在数字之间和任何基数说明符之后使用单个下划线。不允许前导、尾随或连续多个下划线。
字符串格式化 语言现在也支持 '_'
选项,用于指示浮点表示类型和整数表示类型 'd'
使用下划线作为千位分隔符。对于整数表示类型 'b'
、'o'
、'x'
和 'X'
,每 4 位插入下划线
>>> '{:_}'.format(1000000)
'1_000_000'
>>> '{:_x}'.format(0xFFFFFFFF)
'ffff_ffff'
参见
- PEP 515 – 数字字面量中的下划线
PEP 由 Georg Brandl 和 Serhiy Storchaka 编写。
PEP 525: 异步生成器¶
PEP 492 在 Python 3.5 中引入了对原生协程和 async
/ await
语法的支持。Python 3.5 实现的一个显著限制是无法在同一函数体中使用 await
和 yield
。在 Python 3.6 中,此限制已解除,使得定义 异步生成器 成为可能
async def ticker(delay, to):
"""Yield numbers from 0 to *to* every *delay* seconds."""
for i in range(to):
yield i
await asyncio.sleep(delay)
新语法允许更快、更简洁的代码。
参见
- PEP 525 – 异步生成器
PEP 由 Yury Selivanov 编写和实现。
PEP 530: 异步推导式¶
PEP 530 增加了在列表、集合、字典推导式和生成器表达式中使用 async for
的支持
result = [i async for i in aiter() if i % 2]
此外,所有类型的推导式都支持 await
表达式
result = [await fun() for fun in funcs if await condition()]
参见
- PEP 530 – 异步推导式
PEP 由 Yury Selivanov 编写和实现。
PEP 487: 更简单的类创建自定义¶
现在可以在不使用元类的情况下自定义子类创建。每当创建新子类时,都会在基类上调用新的 __init_subclass__
类方法
class PluginBase:
subclasses = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.subclasses.append(cls)
class Plugin1(PluginBase):
pass
class Plugin2(PluginBase):
pass
为了使无参数的 super()
调用能够从 __init_subclass__()
实现中正确工作,自定义元类必须确保新的 __classcell__
命名空间条目传播到 type.__new__
(如 创建类对象 中所述)。
PEP 487: 描述符协议增强¶
PEP 487 扩展了描述符协议,包括新的可选 __set_name__()
方法。每当定义一个新类时,将在定义中包含的所有描述符上调用新方法,向它们提供对正在定义的类及其在类命名空间中赋予描述符的名称的引用。换句话说,描述符的实例现在可以知道所有者类中描述符的属性名称
class IntField:
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not isinstance(value, int):
raise ValueError(f'expecting integer in {self.name}')
instance.__dict__[self.name] = value
# this is the new initializer:
def __set_name__(self, owner, name):
self.name = name
class Model:
int_field = IntField()
PEP 519: 添加文件系统路径协议¶
文件系统路径历来以 str
或 bytes
对象表示。这导致编写操作文件系统路径的代码的人假设此类对象只有这两种类型之一(表示文件描述符的 int
不算作文件路径)。不幸的是,这种假设阻止了文件系统路径的其他对象表示(如 pathlib
)与现有代码(包括 Python 的标准库)一起工作。
为了解决这种情况,定义了一个由 os.PathLike
表示的新接口。通过实现 __fspath__()
方法,对象表示它是一个路径。然后,对象可以提供文件系统路径的低级表示,作为 str
或 bytes
对象。这意味着如果对象实现 os.PathLike
或者是一个表示文件系统路径的 str
或 bytes
对象,则认为该对象是 类路径对象。代码可以使用 os.fspath()
、os.fsdecode()
或 os.fsencode()
显式获取类路径对象的 str
和/或 bytes
表示。
内置函数 open()
已更新,以接受 os.PathLike
对象,os
和 os.path
模块中的所有相关函数以及标准库中的大多数其他函数和类也已更新。 os.DirEntry
类和 pathlib
中的相关类也已更新以实现 os.PathLike
。
希望更新操作文件系统路径的基本函数将导致第三方代码隐式支持所有 类路径对象,而无需任何代码更改,或至少只需要极少的更改(例如,在操作类路径对象之前在代码开头调用 os.fspath()
)。
以下是一些新接口如何使 pathlib.Path
更容易、更透明地与现有代码一起使用的示例
>>> import pathlib
>>> with open(pathlib.Path("README")) as f:
... contents = f.read()
...
>>> import os.path
>>> os.path.splitext(pathlib.Path("some_file.txt"))
('some_file', '.txt')
>>> os.path.join("/a/b", pathlib.Path("c"))
'/a/b/c'
>>> import os
>>> os.fspath(pathlib.Path("some_file.txt"))
'some_file.txt'
(由 Brett Cannon、Ethan Furman、Dusty Phillips 和 Jelle Zijlstra 贡献。)
参见
- PEP 519 – 添加文件系统路径协议
PEP 由 Brett Cannon 和 Koos Zevenhoven 编写。
PEP 495: 本地时间消歧¶
在世界上大多数地方,曾发生过并且将发生本地时钟回拨的情况。在这些时候,会引入一些时间间隔,其中本地时钟在同一天两次显示相同的时间。在这些情况下,本地时钟显示的信息(或存储在 Python datetime 实例中)不足以识别特定时间点。
PEP 495 为 datetime.datetime
和 datetime.time
类的实例添加了新的 fold 属性,以区分在本地时间相同的情况下两个时间点
>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> for i in range(4):
... u = u0 + i*HOUR
... t = u.astimezone(Eastern)
... print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0
除了表示歧义情况下的第二个(按时间顺序)时间点的实例外,fold
属性的值对于所有实例都为 0
。
参见
- PEP 495 – 本地时间消歧
PEP 由 Alexander Belopolsky 和 Tim Peters 编写,由 Alexander Belopolsky 实现。
PEP 529: 将 Windows 文件系统编码更改为 UTF-8¶
表示文件系统路径最好使用 str (Unicode) 而不是 bytes。但是,在某些情况下,使用 bytes 是足够且正确的。
在 Python 3.6 之前,在 Windows 上使用 bytes 路径可能会导致数据丢失。通过此更改,现在在 Windows 上支持使用 bytes 表示路径,前提是这些 bytes 使用 sys.getfilesystemencoding()
返回的编码进行编码,该编码现在默认为 'utf-8'
。
不使用 str 表示路径的应用程序应使用 os.fsencode()
和 os.fsdecode()
来确保其 bytes 已正确编码。要恢复到以前的行为,请设置 PYTHONLEGACYWINDOWSFSENCODING
或调用 sys._enablelegacywindowsfsencoding()
。
有关更多信息和可能需要的代码修改的讨论,请参阅 PEP 529。
PEP 528: 将 Windows 控制台编码更改为 UTF-8¶
Windows 上的默认控制台现在将接受所有 Unicode 字符,并向 Python 代码提供正确读取的 str 对象。sys.stdin
、sys.stdout
和 sys.stderr
现在默认为 utf-8 编码。
此更改仅适用于交互式控制台,而不适用于重定向文件或管道。要恢复交互式控制台使用的以前行为,请设置 PYTHONLEGACYWINDOWSSTDIO
。
参见
- PEP 528 – 将 Windows 控制台编码更改为 UTF-8
PEP 由 Steve Dower 编写和实现。
PEP 520: 保留类属性定义顺序¶
类定义体中的属性具有自然顺序:名称在源代码中出现的相同顺序。此顺序现在保留在新类的 __dict__
属性中。
此外,有效的默认类 执行 命名空间(从 type.__prepare__() 返回)现在是一个保持插入顺序的映射。
参见
- PEP 520 – 保留类属性定义顺序
PEP 由 Eric Snow 编写和实现。
PEP 468: 保留关键字参数顺序¶
函数签名中的 **kwargs
现在保证是保持插入顺序的映射。
参见
- PEP 468 – 保留关键字参数顺序
PEP 由 Eric Snow 编写和实现。
新的 dict 实现¶
dict 类型现在使用基于 Raymond Hettinger 提案 的“紧凑”表示,该提案 最初由 PyPy 实现。与 Python 3.5 相比,新的 dict()
的内存使用量减少了 20% 到 25%。
此新实现的保持顺序方面被认为是实现细节,不应依赖(未来可能会改变,但希望此新 dict 实现能在语言中存在几个版本,然后才更改语言规范以强制所有当前和未来 Python 实现的保持顺序语义;这也有助于保持与旧语言版本(其中随机迭代顺序仍然有效,例如 Python 3.5)的向后兼容性)。
(由 INADA Naoki 在 bpo-27350 中贡献。想法 最初由 Raymond Hettinger 提出。)
PEP 523: 向 CPython 添加帧评估 API¶
虽然 Python 提供了广泛的支持来定制代码的执行方式,但它在帧对象的评估方面却没有这样做。如果您想要某种方式来拦截 Python 中的帧评估,那么除了直接操作已定义函数的函数指针之外,实际上没有任何办法。
PEP 523 通过提供一个 API 来在 C 级别上使帧评估可插拔,从而改变了这一点。这将允许调试器和 JIT 等工具在 Python 代码执行开始之前拦截帧评估。这使得可以使用替代的 Python 代码评估实现、跟踪帧评估等。
此 API 不属于受限 C API,并被标记为私有,以表明此 API 的使用预计将受到限制,并且仅适用于非常特定的低级用例。API 的语义将根据需要随 Python 更改。
参见
- PEP 523 – 向 CPython 添加帧评估 API
PEP 由 Brett Cannon 和 Dino Viehland 编写。
PYTHONMALLOC 环境变量¶
新的 PYTHONMALLOC
环境变量允许设置 Python 内存分配器并安装调试钩子。
现在可以使用 PYTHONMALLOC=debug
在以发布模式编译的 Python 上安装 Python 内存分配器上的调试钩子。调试钩子的效果
新分配的内存用字节
0xCB
填充释放的内存用字节
0xDB
填充检测违反 Python 内存分配器 API 的情况。例如,在由
PyMem_Malloc()
分配的内存块上调用PyObject_Free()
。检测缓冲区开始之前的写入(缓冲区下溢)
检测缓冲区结束之后的写入(缓冲区溢出)
检查在调用
PYMEM_DOMAIN_OBJ
(例如:PyObject_Malloc()
)和PYMEM_DOMAIN_MEM
(例如:PyMem_Malloc()
)域的分配器函数时是否持有 GIL。
检查是否持有 GIL 也是 Python 3.6 的一个新功能。
有关 Python 内存分配器上的调试钩子,请参阅 PyMem_SetupDebugHooks()
函数。
现在还可以使用 PYTHONMALLOC=malloc
强制所有 Python 内存分配使用 C 库的 malloc()
分配器。这在使用 Valgrind 等外部内存调试器对以发布模式编译的 Python 进行调试时很有帮助。
出现错误时,Python 内存分配器上的调试钩子现在使用 tracemalloc
模块获取分配内存块的回溯。
使用 python3.6 -X tracemalloc=5
(在跟踪中存储 5 个帧)时缓冲区溢出的致命错误示例
Debug memory block at address p=0x7fbcd41666f8: API 'o'
4 bytes originally requested
The 7 pad bytes at p-7 are FORBIDDENBYTE, as expected.
The 8 pad bytes at tail=0x7fbcd41666fc are not all FORBIDDENBYTE (0xfb):
at tail+0: 0x02 *** OUCH
at tail+1: 0xfb
at tail+2: 0xfb
at tail+3: 0xfb
at tail+4: 0xfb
at tail+5: 0xfb
at tail+6: 0xfb
at tail+7: 0xfb
The block was made by call #1233329 to debug malloc/realloc.
Data at p: 1a 2b 30 00
Memory block allocated at (most recent call first):
File "test/test_bytes.py", line 323
File "unittest/case.py", line 600
File "unittest/case.py", line 648
File "unittest/suite.py", line 122
File "unittest/suite.py", line 84
Fatal Python error: bad trailing pad byte
Current thread 0x00007fbcdbd32700 (most recent call first):
File "test/test_bytes.py", line 323 in test_hex
File "unittest/case.py", line 600 in run
File "unittest/case.py", line 648 in __call__
File "unittest/suite.py", line 122 in run
File "unittest/suite.py", line 84 in __call__
File "unittest/suite.py", line 122 in run
File "unittest/suite.py", line 84 in __call__
...
DTrace 和 SystemTap 探测支持¶
Python 现在可以构建 --with-dtrace
,这会为解释器中的以下事件启用静态标记
函数调用/返回
垃圾回收开始/结束
执行的代码行。
这可用于在生产中检测正在运行的解释器,而无需重新编译特定的 调试版本 或提供应用程序特定的性能分析/调试代码。
更多详细信息请参见 使用 DTrace 和 SystemTap 检测 CPython。
当前的实现已在 Linux 和 macOS 上测试。未来可能会添加更多标记。
(由 Łukasz Langa 在 bpo-21590 中贡献,基于 Jesús Cea Avión、David Malcolm 和 Nikhil Benesch 的补丁。)
其他语言更改¶
对核心 Python 语言做了一些较小的更改
global
或nonlocal
语句现在必须在同一作用域内受影响名称的第一次使用之前文本性地出现。以前这是一个SyntaxWarning
。现在可以将 特殊方法 设置为
None
,以指示相应的操作不可用。例如,如果一个类将__iter__()
设置为None
,则该类不可迭代。(由 Andrew Barnert 和 Ivan Levkivskyi 在 bpo-25958 中贡献。)长序列的重复回溯行现在缩写为
"[Previous line repeated {count} more times]"
(参见 回溯 以获得示例)。(由 Emanuel Barry 在 bpo-26823 中贡献。)当无法找到模块时,import 现在会引发新的异常
ModuleNotFoundError
(ImportError
的子类)。目前检查 ImportError(在 try-except 中)的代码仍然有效。(由 Eric Snow 在 bpo-15767 中贡献。)依赖于无参数
super()
的类方法现在在类创建期间从元类方法调用时将正确工作。(由 Martin Teichmann 在 bpo-23722 中贡献。)
新模块¶
secrets¶
新的 secrets
模块的主要目的是提供一种显而易见的方法,可靠地生成加密强度伪随机值,适用于管理帐户认证、令牌等密钥。
警告
请注意,random
模块中的伪随机生成器 不应 用于安全目的。在 Python 3.6 及更高版本上使用 secrets
,在 Python 3.5 及更早版本上使用 os.urandom()
。
参见
- PEP 506 – 向标准库添加 Secrets 模块
PEP 由 Steven D’Aprano 编写和实现。
改进的模块¶
array¶
array.array
的耗尽迭代器现在即使迭代的数组被扩展,也将保持耗尽状态。这与其他可变序列的行为一致。
由 Serhiy Storchaka 在 bpo-26492 中贡献。
ast¶
已添加新的 ast.Constant
AST 节点。外部 AST 优化器可以使用它进行常量折叠。
由 Victor Stinner 在 bpo-26146 中贡献。
asyncio¶
从 Python 3.6 开始,asyncio
模块不再是临时性的,其 API 被认为是稳定的。
自 Python 3.5.0 以来 asyncio
模块的显著更改(由于临时状态,所有更改都已回溯到 3.5.x)
get_event_loop()
函数已更改为从协程和回调调用时始终返回当前运行的循环。(由 Yury Selivanov 在 bpo-28613 中贡献。)ensure_future()
函数以及所有使用它的函数,例如loop.run_until_complete()
,现在接受所有类型的 可等待对象。(由 Yury Selivanov 贡献。)新的
run_coroutine_threadsafe()
函数用于从其他线程向事件循环提交协程。(由 Vincent Michel 贡献。)新的
Transport.is_closing()
方法用于检查传输是否正在关闭或已关闭。(由 Yury Selivanov 贡献。)loop.create_server()
方法现在可以接受主机列表。(由 Yann Sionneau 贡献。)新的
loop.create_future()
方法用于创建 Future 对象。这允许替代事件循环实现(例如 uvloop)提供更快的asyncio.Future
实现。(由 Yury Selivanov 在 bpo-27041 中贡献。)新的
loop.get_exception_handler()
方法用于获取当前的异常处理程序。(由 Yury Selivanov 在 bpo-27040 中贡献。)新的
StreamReader.readuntil()
方法用于从流中读取数据,直到出现分隔符字节序列。(由 Mark Korenberg 贡献。)StreamReader.readexactly()
的性能已得到改进。(由 Mark Korenberg 在 bpo-28370 中贡献。)loop.getaddrinfo()
方法已优化,如果地址已解析,则避免调用系统getaddrinfo
函数。(由 A. Jesse Jiryu Davis 贡献。)loop.stop()
方法已更改为在当前迭代后立即停止循环。作为上次迭代结果的任何新调度回调都将被丢弃。(由 Guido van Rossum 在 bpo-25593 中贡献。)Future.set_exception
现在在传递StopIteration
异常的实例时将引发TypeError
。(由 Chris Angelico 在 bpo-26221 中贡献。)新的
loop.connect_accepted_socket()
方法供在 asyncio 之外接受连接但使用 asyncio 处理它们的服务器使用。(由 Jim Fulton 在 bpo-27392 中贡献。)默认情况下,所有 TCP 传输现在都设置了
TCP_NODELAY
标志。(由 Yury Selivanov 在 bpo-27456 中贡献。)新的
loop.shutdown_asyncgens()
用于在关闭循环之前正确关闭待处理的异步生成器。(由 Yury Selivanov 在 bpo-28003 中贡献。)Future
和Task
类现在具有优化的 C 实现,这使得 asyncio 代码速度提高了 30%。(由 Yury Selivanov 和 INADA Naoki 在 bpo-26081 和 bpo-28544 中贡献。)
binascii¶
b2a_base64()
函数现在接受可选的 newline 关键字参数,以控制是否将换行符附加到返回值。(由 Victor Stinner 在 bpo-25357 中贡献。)
cmath¶
已添加新的 cmath.tau
(τ) 常量。(由 Lisa Roach 在 bpo-12345 中贡献,有关详细信息请参见 PEP 628。)
新常量:cmath.inf
和 cmath.nan
以匹配 math.inf
和 math.nan
,以及 cmath.infj
和 cmath.nanj
以匹配复杂 repr 使用的格式。(由 Mark Dickinson 在 bpo-23229 中贡献。)
collections¶
已添加新的 Collection
抽象基类,用于表示有大小的可迭代容器类。(由 Ivan Levkivskyi 贡献,文档由 Neil Girdhar 在 bpo-27598 中编写。)
新的 Reversible
抽象基类表示也提供 __reversed__()
方法的可迭代类。(由 Ivan Levkivskyi 在 bpo-25987 中贡献。)
新的 AsyncGenerator
抽象基类表示异步生成器。(由 Yury Selivanov 在 bpo-28720 中贡献。)
namedtuple()
函数现在接受可选的关键字参数 module,当指定时,它将用于返回的命名元组类的 __module__
属性。(由 Raymond Hettinger 在 bpo-17941 中贡献。)
namedtuple()
的 verbose 和 rename 参数现在仅限关键字。(由 Raymond Hettinger 在 bpo-25628 中贡献。)
递归的 collections.deque
实例现在可以被 pickle。(由 Serhiy Storchaka 在 bpo-26482 中贡献。)
concurrent.futures¶
ThreadPoolExecutor
类构造函数现在接受可选的 thread_name_prefix 参数,以便可以自定义由池创建的线程的名称。(由 Gregory P. Smith 在 bpo-27664 中贡献。)
contextlib¶
已添加 contextlib.AbstractContextManager
类,用于为上下文管理器提供抽象基类。它为 __enter__()
提供了合理的默认实现,该实现返回 self
并将 __exit__()
留作抽象方法。已向 typing
模块添加了一个匹配的类作为 typing.ContextManager
。(由 Brett Cannon 在 bpo-25609 中贡献。)
datetime¶
datetime
和 time
类具有新的 fold
属性,用于在必要时消除本地时间的歧义。datetime
中的许多函数已更新以支持本地时间消歧。有关更多信息,请参阅 本地时间消歧 部分。(由 Alexander Belopolsky 在 bpo-24773 中贡献。)
datetime.strftime()
和 date.strftime()
方法现在支持 ISO 8601 日期指令 %G
、%u
和 %V
。(由 Ashley Anderson 在 bpo-12006 中贡献。)
datetime.isoformat()
函数现在接受可选的 timespec 参数,该参数指定要包含的时间值的附加组件的数量。(由 Alessandro Cucci 和 Alexander Belopolsky 在 bpo-19475 中贡献。)
datetime.combine()
现在接受可选的 tzinfo 参数。(由 Alexander Belopolsky 在 bpo-27661 中贡献。)
decimal¶
新的 Decimal.as_integer_ratio()
方法,返回一对 (n, d)
整数,表示给定的 Decimal
实例作为分数,以最简形式和正分母
>>> Decimal('-3.14').as_integer_ratio()
(-157, 50)
(由 Stefan Krah 和 Mark Dickinson 在 bpo-25928 中贡献。)
distutils¶
default_format
属性已从 distutils.command.sdist.sdist
中移除,formats
属性默认为 ['gztar']
。尽管未曾预料,任何依赖于 default_format
的代码可能需要进行调整。有关更多详细信息,请参见 bpo-27819。
email¶
通过构造函数的 policy 关键字启用的新 email API 不再是临时性的。email
文档已重新组织和重写,以专注于新 API,同时保留旧文档用于传统 API。(由 R. David Murray 在 bpo-24277 中贡献。)
email.mime
类现在都接受可选的 policy 关键字。(由 Berker Peksag 在 bpo-27331 中贡献。)
DecodedGenerator
现在支持 policy 关键字。
有一个新的 policy
属性 message_factory
,它控制解析器创建新消息对象时默认使用的类。对于 email.policy.compat32
策略,这是 Message
,对于新策略,它是 EmailMessage
。(由 R. David Murray 在 bpo-20476 中贡献。)
encodings¶
在 Windows 上,添加了 'oem'
编码以使用 CP_OEMCP
,以及现有 'mbcs'
编码的 'ansi'
别名,该编码使用 CP_ACP
代码页。(由 Steve Dower 在 bpo-27959 中贡献。)
enum¶
enum
模块中添加了两个新的枚举基类:Flag
和 IntFlag
。两者都用于定义可以使用位运算符组合的常量。(由 Ethan Furman 在 bpo-23591 中贡献。)
许多标准库模块已更新,以使用 IntFlag
类作为其常量。
新的 enum.auto
值可用于自动为枚举成员赋值
>>> from enum import Enum, auto
>>> class Color(Enum):
... red = auto()
... blue = auto()
... green = auto()
...
>>> list(Color)
[<Color.red: 1>, <Color.blue: 2>, <Color.green: 3>]
faulthandler¶
在 Windows 上,faulthandler
模块现在为 Windows 异常安装了一个处理程序:请参见 faulthandler.enable()
。(由 Victor Stinner 在 bpo-23848 中贡献。)
fileinput¶
hook_encoded()
现在支持 errors 参数。(由 Joseph Hackman 在 bpo-25788 中贡献。)
hashlib¶
hashlib
支持 OpenSSL 1.1.0。建议的最低版本是 1.0.2。(由 Christian Heimes 在 bpo-26470 中贡献。)
BLAKE2 哈希函数已添加到模块中。blake2b()
和 blake2s()
始终可用,并支持 BLAKE2 的全部功能集。(由 Christian Heimes 在 bpo-26798 中贡献,基于 Dmitry Chestnykh 和 Samuel Neves 的代码。文档由 Dmitry Chestnykh 编写。)
SHA-3 哈希函数 sha3_224()
、sha3_256()
、sha3_384()
、sha3_512()
,以及 SHAKE 哈希函数 shake_128()
和 shake_256()
已添加。(由 Christian Heimes 在 bpo-16113 中贡献。Keccak 代码包由 Guido Bertoni、Joan Daemen、Michaël Peeters、Gilles Van Assche 和 Ronny Van Keer 贡献。)
密码派生函数 scrypt()
现在可用于 OpenSSL 1.1.0 及更高版本。(由 Christian Heimes 在 bpo-27928 中贡献。)
http.client¶
HTTPConnection.request()
和 endheaders()
现在都支持分块编码请求体。(由 Demian Brecht 和 Rolf Krahl 在 bpo-12319 中贡献。)
idlelib 和 IDLE¶
idlelib 包正在现代化和重构,以使 IDLE 外观和工作更好,并使代码更易于理解、测试和改进。使 IDLE 外观更好(尤其是在 Linux 和 Mac 上)的一部分是使用 ttk 小部件,主要在对话框中。因此,IDLE 不再与 tcl/tk 8.4 一起运行。现在它需要 tcl/tk 8.5 或 8.6。我们建议运行任何一个的最新版本。
“现代化”包括 idlelib 模块的重命名和整合。部分大写名称的文件的重命名类似于 3.0 中 Tkinter 和 TkFont 重命名为 tkinter 和 tkinter.font。因此,在 3.5 中有效的 idlelib 文件导入通常在 3.6 中无效。至少需要更改模块名称(请参见 idlelib/README.txt),有时需要更多。(名称更改由 Al Swiegart 和 Terry Reedy 在 bpo-24225 中贡献。此后的大多数 idlelib 补丁已并将成为该过程的一部分。)
作为补偿,最终结果将是某些 idlelib 类将更容易使用,具有更好的 API 和解释它们的文档字符串。当可用时,将向 idlelib 添加更多有用信息。
3.6.2 中的新增功能
自动补全的多次修复。(由Louie Lu在bpo-15786贡献。)
3.6.3 版新增
模块浏览器(在“文件”菜单中,以前称为“类浏览器”)现在除了顶级函数和类之外,还显示嵌套函数和类。(由Guilherme Polo、Cheryl Sabella和Terry Jan Reedy在bpo-1612262贡献。)
以前作为扩展实现的IDLE功能已重新实现为常规功能。它们的设置已从“扩展”选项卡移至其他对话框选项卡。(由Charles Wohlganger和Terry Jan Reedy在bpo-27099贡献。)
“设置”对话框(选项,配置IDLE)已部分重写,以改善外观和功能。(由Cheryl Sabella和Terry Jan Reedy在多个问题中贡献。)
3.6.4 版新增
字体样本现在包含一系列非拉丁字符,以便用户更好地查看选择特定字体的效果。(由Terry Jan Reedy在bpo-13802贡献。)样本可以编辑以包含其他字符。(由Serhiy Storchaka在bpo-31860贡献。)
3.6.6 版新增
编辑器代码上下文选项已修订。框显示所有上下文行,最多显示 maxlines。单击上下文行会将编辑器跳转到该行。自定义主题的上下文颜色已添加到“设置”对话框的“高亮显示”选项卡。(由Cheryl Sabella和Terry Jan Reedy在bpo-33642、bpo-33768和bpo-33679贡献。)
在 Windows 上,一个新的 API 调用告诉 Windows,tk 按 DPI 缩放。在 Windows 8.1+ 或 10 上,如果 Python 二进制文件的 DPI 兼容性属性未更改,并且显示器分辨率大于 96 DPI,这应该使文本和线条更清晰。否则应该没有影响。(由Terry Jan Reedy在bpo-33656贡献。)
3.6.7 版新增
超出 N 行(默认为 50 行)的输出会被压缩成一个按钮。N 可以在“设置”对话框的“通用”页面的“PyShell”部分更改。通过右键单击输出,可以压缩更少但可能过长的行。压缩后的输出可以通过双击按钮在原地展开,或通过右键单击按钮展开到剪贴板或单独的窗口中。(由 Tal Einat 在bpo-1529353中贡献。)
importlib¶
当无法找到模块时,import 现在会引发新的异常 ModuleNotFoundError
(它是 ImportError
的子类)。当前检查 ImportError
(在 try-except 中) 的代码仍然有效。(由Eric Snow在bpo-15767贡献。)
importlib.util.LazyLoader
现在会在包装的加载器上调用 create_module()
,移除了 importlib.machinery.BuiltinImporter
和 importlib.machinery.ExtensionFileLoader
不能与 importlib.util.LazyLoader
一起使用的限制。
importlib.util.cache_from_source()
、importlib.util.source_from_cache()
和 importlib.util.spec_from_file_location()
现在接受 类路径对象。
inspect¶
inspect.signature()
函数现在将编译器为推导式和生成器表达式作用域生成的隐式 .0
参数报告为名为 implicit0
的仅位置参数。(由Jelle Zijlstra在bpo-19611贡献。)
为了减少从 Python 2.7 和旧版 inspect.getargspec()
API 升级时的代码修改,之前记录的 inspect.getfullargspec()
的弃用已被撤销。虽然此函数对于单/源 Python 2/3 代码库很方便,但更丰富的 inspect.signature()
接口仍然是新代码的推荐方法。(由Nick Coghlan在bpo-27172贡献)
json¶
json.load()
和 json.loads()
现在支持二进制输入。编码的 JSON 应该使用 UTF-8、UTF-16 或 UTF-32 表示。(由Serhiy Storchaka在bpo-17909贡献。)
logging¶
新增了 WatchedFileHandler.reopenIfNeeded()
方法,以增加检查日志文件是否需要重新打开的功能。(由Marian Horban在bpo-24884贡献。)
math¶
常数 tau (τ) 已添加到 math
和 cmath
模块中。(由Lisa Roach在bpo-12345贡献,详见 PEP 628。)
multiprocessing¶
multiprocessing.Manager()
返回的 代理对象 现在可以嵌套。(由Davin Potts在bpo-6766贡献。)
os¶
有关 PEP 519 的摘要,请参阅 os
和 os.path
模块现在如何支持 类路径对象 的详细信息。
scandir()
现在支持 Windows 上的 bytes
路径。
新增了 close()
方法,允许显式关闭 scandir()
迭代器。scandir()
迭代器现在支持 上下文管理器 协议。如果 scandir()
迭代器既未耗尽也未显式关闭,则在其析构函数中会发出 ResourceWarning
警告。(由Serhiy Storchaka在bpo-25994贡献。)
在 Linux 上,os.urandom()
现在会阻塞,直到系统 urandom 熵池初始化以提高安全性。有关理由,请参阅 PEP 524。
Linux getrandom()
系统调用(获取随机字节)现在作为新的 os.getrandom()
函数公开。(由Victor Stinner贡献,是 PEP 524 的一部分)
pathlib¶
pathlib
现在支持 类路径对象。(由Brett Cannon在bpo-27186贡献。)
有关详细信息,请参阅 PEP 519 的摘要。
pdb¶
Pdb
类构造函数新增了可选的 readrc 参数,用于控制是否应该读取 .pdbrc
文件。
pickle¶
需要使用关键字参数调用 __new__
的对象现在可以使用早于协议版本 4 的 pickle 协议 进行 pickle。协议版本 4 已经支持这种情况。(由Serhiy Storchaka在bpo-24164贡献。)
pickletools¶
pickletools.dis()
现在为 MEMOIZE
操作码输出隐式备忘录索引。(由Serhiy Storchaka在bpo-25382贡献。)
pydoc¶
pydoc
模块已经学会了遵循 MANPAGER
环境变量。(由Matthias Klose在bpo-8637贡献。)
help()
和 pydoc
现在可以按定义顺序而不是按字母顺序列出命名元组字段。(由Raymond Hettinger在bpo-24879贡献。)
random¶
新的 choices()
函数返回一个指定大小的元素列表,该列表从给定总体中获取,并带有可选的权重。(由Raymond Hettinger在bpo-18844贡献。)
re¶
增加了对正则表达式中修饰符范围的支持。例如:'(?i:p)ython'
匹配 'python'
和 'Python'
,但不匹配 'PYTHON'
;'(?i)g(?-i:v)r'
匹配 'GvR'
和 'gvr'
,但不匹配 'GVR'
。(由Serhiy Storchaka在bpo-433028贡献。)
匹配对象组可以通过 __getitem__
访问,这等同于 group()
。因此 mo['name']
现在等同于 mo.group('name')
。(由Eric Smith在bpo-24454贡献。)
Match
对象现在支持 类索引对象
作为组索引。(由Jeroen Demeyer和Xiang Zhang在bpo-27177贡献。)
readline¶
添加了 set_auto_history()
来启用或禁用自动将输入添加到历史列表。(由Tyler Crompton在bpo-26870贡献。)
rlcompleter¶
私有和特殊属性名称现在被省略,除非前缀以下划线开头。某些已完成的关键字后面会添加一个空格或冒号。(由Serhiy Storchaka在bpo-25011和bpo-25209贡献。)
shlex¶
shlex
通过新的 punctuation_chars 参数来控制哪些字符被视为标点符号,从而大大改进了 shell 兼容性。(由Vinay Sajip在bpo-1521950贡献。)
site¶
在 .pth
文件中指定要添加到 sys.path
的路径时,现在可以在目录(例如 zip 文件)之上指定文件路径。(由Wolfgang Langner在bpo-26587贡献)。
sqlite3¶
sqlite3.Cursor.lastrowid
现在支持 REPLACE
语句。(由Alex LordThorsen在bpo-16864贡献。)
socket¶
ioctl()
函数现在支持 SIO_LOOPBACK_FAST_PATH
控制代码。(由Daniel Stokes在bpo-26536贡献。)
现在支持 getsockopt()
常量 SO_DOMAIN
、SO_PROTOCOL
、SO_PEERSEC
和 SO_PASSSEC
。(由Christian Heimes在bpo-26907贡献。)
setsockopt()
现在支持 setsockopt(level, optname, None, optlen: int)
形式。(由Christian Heimes在bpo-27744贡献。)
socket 模块现在支持地址族 AF_ALG
,以与 Linux 内核加密 API 交互。添加了 ALG_*
、SOL_ALG
和 sendmsg_afalg()
。(由Christian Heimes在bpo-27744贡献,并得到了Victor Stinner的支持。)
新增了 Linux 常量 TCP_USER_TIMEOUT
和 TCP_CONGESTION
。(由Omar Sandoval在bpo-26273贡献。)
socketserver¶
基于 socketserver
模块的服务器,包括 http.server
、xmlrpc.server
和 wsgiref.simple_server
中定义的服务器,现在支持 上下文管理器 协议。(由Aviv Palivoda在bpo-26404贡献。)
StreamRequestHandler
类的 wfile
属性现在实现了 io.BufferedIOBase
可写接口。特别是,现在保证调用 write()
会完全发送数据。(由Martin Panter在bpo-26721贡献。)
ssl¶
ssl
支持 OpenSSL 1.1.0。建议的最低版本是 1.0.2。(由Christian Heimes在bpo-26470贡献。)
3DES 已从默认密码套件中移除,并添加了 ChaCha20 Poly1305 密码套件。(由Christian Heimes在bpo-27850和bpo-27766贡献。)
SSLContext
对选项和密码具有更好的默认配置。(由Christian Heimes在bpo-28043贡献。)
SSL 会话可以使用新的 SSLSession
类从一个客户端连接复制到另一个客户端连接。TLS 会话恢复可以加快初始握手,减少延迟并提高性能。(由Christian Heimes在bpo-19500贡献,基于Alex Warhawk的草稿。)
可以使用新的 get_ciphers()
方法获取按密码优先级排序的已启用密码列表。
所有常量和标志都已转换为 IntEnum
和 IntFlag
。(由Christian Heimes在bpo-28025贡献。)
为 SSLContext
添加了服务器端和客户端特定的 TLS 协议。(由Christian Heimes在bpo-28085贡献。)
新增了 ssl.SSLContext.post_handshake_auth
用于启用,以及 ssl.SSLSocket.verify_client_post_handshake()
用于启动 TLS 1.3 握手后认证。(由Christian Heimes在gh-78851贡献。)
statistics¶
新增了 harmonic_mean()
函数。(由Steven D’Aprano在bpo-27181贡献。)
struct¶
struct
现在通过 'e'
格式说明符支持 IEEE 754 半精度浮点数。(由Eli Stevens、Mark Dickinson在bpo-11734贡献。)
subprocess¶
subprocess.Popen
析构函数现在会在子进程仍在运行时发出 ResourceWarning
警告。使用上下文管理器协议 (with proc: ...
) 或显式调用 wait()
方法来读取子进程的退出状态。(由Victor Stinner在bpo-26741贡献。)
subprocess.Popen
构造函数和所有通过它传递参数的函数现在都接受 encoding 和 errors 参数。指定其中任何一个都将为 stdin、stdout 和 stderr 流启用文本模式。(由Steve Dower在bpo-6135贡献。)
sys¶
新的 getfilesystemencodeerrors()
函数返回用于在 Unicode 文件名和字节文件名之间转换的错误模式的名称。(由Steve Dower在bpo-27781贡献。)
在 Windows 上,getwindowsversion()
函数的返回值现在包含 platform_version 字段,其中包含当前操作系统的准确主要版本、次要版本和构建号,而不是为进程模拟的版本。(由Steve Dower在bpo-27932贡献。)
telnetlib¶
telnetlib.Telnet
现在是一个上下文管理器(由Stéphane Wirtel在bpo-25485贡献)。
时间¶
struct_time
属性 tm_gmtoff
和 tm_zone
现在在所有平台上可用。
timeit¶
新的 Timer.autorange()
便捷方法已被添加,用于重复调用 Timer.timeit()
,以便总运行时间大于或等于 200 毫秒。(由Steven D’Aprano在bpo-6422贡献。)
timeit
现在会在最佳时间和最差时间之间存在显著(4 倍)差异时发出警告。(由Serhiy Storchaka在bpo-23552贡献。)
tkinter¶
在 tkinter.Variable
类中添加了方法 Variable.trace_add()
、Variable.trace_remove()
和 trace_info()
。它们替换了使用过时 Tcl 命令且可能在未来 Tcl 版本中不起作用的旧方法 trace_variable()
、trace()
、trace_vdelete()
和 trace_vinfo()
。(由Serhiy Storchaka在bpo-22115贡献)。
traceback¶
追溯模块和解释器的内置异常显示现在都会缩写追溯中重复行的长序列,如以下示例所示
>>> def f(): f()
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in f
File "<stdin>", line 1, in f
File "<stdin>", line 1, in f
[Previous line repeated 995 more times]
RecursionError: maximum recursion depth exceeded
(由Emanuel Barry在bpo-26823贡献。)
tracemalloc¶
tracemalloc
模块现在支持在多个不同地址空间中追踪内存分配。
新增了 DomainFilter
过滤器类,用于按地址空间(域)过滤块跟踪。
(由Victor Stinner在bpo-26588贡献。)
typing¶
由于 typing
模块是 临时性API,因此 Python 3.6 中引入的所有更改也已向后移植到 Python 3.5.x。
typing
模块大大改进了对泛型类型别名的支持。例如,Dict[str, Tuple[S, T]]
现在是有效的类型注解。(由Guido van Rossum在Github #195贡献。)
新增了 typing.ContextManager
类,用于表示 contextlib.AbstractContextManager
。(由Brett Cannon在bpo-25609贡献。)
新增了 typing.Collection
类,用于表示 collections.abc.Collection
。(由Ivan Levkivskyi在bpo-27598贡献。)
添加了 typing.ClassVar
类型结构以标记类变量。如 PEP 526 中介绍的,用 ClassVar 包装的变量注解表示给定属性旨在用作类变量,不应在类的实例上设置。(由Ivan Levkivskyi在Github #280贡献。)
一个新的 TYPE_CHECKING
常量,静态类型检查器假定它为 True
,但在运行时为 False
。(由Guido van Rossum在Github #230贡献。)
新增了 NewType()
辅助函数,用于为注解创建轻量级、不同的类型。
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
静态类型检查器会将新类型视为原始类型的子类。(由Ivan Levkivskyi在Github #189贡献。)
unicodedata¶
unicodedata
模块现在使用 Unicode 9.0.0 的数据。(由Benjamin Peterson贡献。)
unittest.mock¶
Mock
类具有以下改进
两个新方法,
Mock.assert_called()
和Mock.assert_called_once()
,用于检查模拟对象是否被调用。(由Amit Saha在bpo-26323贡献。)Mock.reset_mock()
方法现在有两个可选的仅限关键字参数:return_value 和 side_effect。(由Kushal Das在bpo-21271贡献。)
urllib.request¶
如果 HTTP 请求有一个文件或可迭代主体(除了字节对象),但没有 Content-Length
头部,AbstractHTTPHandler
现在不会抛出错误,而是回退到使用分块传输编码。(由Demian Brecht和Rolf Krahl在bpo-12319贡献。)
urllib.robotparser¶
RobotFileParser
现在支持 Crawl-delay
和 Request-rate
扩展。(由Nikolay Bogoychev在bpo-16099贡献。)
venv¶
venv
接受一个新的参数 --prompt
。此参数为虚拟环境提供了另一个前缀。(由Łukasz Balcerzak提出,并由Stéphane Wirtel移植到 3.6,在bpo-22829中。)
warnings¶
warnings.warn_explicit()
函数新增了一个可选的 source 参数:发出 ResourceWarning
的销毁对象。warnings.WarningMessage
也新增了 source 属性(由Victor Stinner在bpo-26568和bpo-26567贡献)。
当记录 ResourceWarning
警告时,现在使用 tracemalloc
模块尝试检索销毁对象分配时的追溯。
使用脚本 example.py
的示例
import warnings
def func():
return open(__file__)
f = func()
f = None
命令 python3.6 -Wd -X tracemalloc=5 example.py
的输出
example.py:7: ResourceWarning: unclosed file <_io.TextIOWrapper name='example.py' mode='r' encoding='UTF-8'>
f = None
Object allocated at (most recent call first):
File "example.py", lineno 4
return open(__file__)
File "example.py", lineno 6
f = func()
“对象分配于”追溯是新增的,并且仅在 tracemalloc
正在追踪 Python 内存分配且 warnings
模块已导入时显示。
winreg¶
winsound¶
允许将关键字参数传递给 Beep
、MessageBeep
和 PlaySound
(bpo-27982)。
xmlrpc.client¶
xmlrpc.client
模块现在支持解组 Apache XML-RPC 实现用于数值和 None
的其他数据类型。(由Serhiy Storchaka在bpo-26885贡献。)
zipfile¶
新的 ZipInfo.from_file()
类方法允许从文件系统文件创建 ZipInfo
实例。新的 ZipInfo.is_dir()
方法可用于检查 ZipInfo
实例是否表示目录。(由Thomas Kluyver在bpo-26039贡献。)
ZipFile.open()
方法现在可以用于向 ZIP 文件写入数据,以及提取数据。(由Thomas Kluyver在bpo-26039贡献。)
zlib¶
compress()
和 decompress()
函数现在接受关键字参数。(分别由Aviv Palivoda在bpo-26243和Xiang Zhang在bpo-16764贡献。)
优化¶
Python 解释器现在使用 16 位字码而不是字节码,这使得许多操作码优化成为可能。(由Demur Rumed在Serhiy Storchaka和Victor Stinner的输入和审查下,在bpo-26647和bpo-28050中贡献。)
asyncio.Future
类现在有了优化的 C 实现。(由Yury Selivanov和INADA Naoki在bpo-26081贡献。)asyncio.Task
类现在有了优化的 C 实现。(由Yury Selivanov在bpo-28544贡献。)typing
模块中的各种实现改进(例如泛型类型的缓存)可将性能提高多达 30 倍,并减少内存占用。ASCII 解码器对于错误处理程序
surrogateescape
、ignore
和replace
现在速度提高了 60 倍。(由Victor Stinner在bpo-24870贡献)。ASCII 和 Latin1 编码器对于错误处理程序
surrogateescape
现在速度提高了 3 倍。(由Victor Stinner在bpo-25227贡献)。UTF-8 编码器对于错误处理程序
ignore
、replace
、surrogateescape
、surrogatepass
现在速度提高了 75 倍。(由Victor Stinner在bpo-25267贡献)。UTF-8 解码器对于错误处理程序
ignore
、replace
和surrogateescape
现在速度提高了 15 倍。(由Victor Stinner在bpo-25301贡献)。bytes % args
现在快了两倍。(由Victor Stinner在bpo-25349贡献)。bytearray % args
现在快了 2.5 到 5 倍。(由Victor Stinner在bpo-25399贡献)。优化
bytes.fromhex()
和bytearray.fromhex()
:它们现在快了 2 倍到 3.5 倍。(由Victor Stinner在bpo-25401贡献)。优化
bytes.replace(b'', b'.')
和bytearray.replace(b'', b'.')
:速度提高了高达 80%。(由Josh Snider在bpo-26574贡献)。PyMem_Malloc()
域 (PYMEM_DOMAIN_MEM
) 的分配器函数现在使用 pymalloc 内存分配器,而不是 C 库的malloc()
函数。pymalloc 分配器针对小于或等于 512 字节且生命周期短的对象进行了优化,并对较大的内存块使用malloc()
。(由Victor Stinner在bpo-26249贡献。)反序列化许多小对象时,
pickle.load()
和pickle.loads()
现在速度提高了 10%。(由Victor Stinner在bpo-27056贡献)。与传递 位置参数 相比,向函数传递 关键字参数 存在开销。现在,在使用 Argument Clinic 实现的扩展函数中,这种开销已显著降低。(由Serhiy Storchaka在bpo-27574贡献。)
优化了
glob
模块中的glob()
和iglob()
函数;它们现在快了大约 3-6 倍。(由Serhiy Storchaka在bpo-25596贡献。)通过使用
os.scandir()
,优化了pathlib
中的 globbing;现在速度提高了大约 1.5-4 倍。(由Serhiy Storchaka在bpo-26032贡献。)xml.etree.ElementTree
的解析、迭代和深层复制性能已显著提高。(由Serhiy Storchaka在bpo-25638、bpo-25873和bpo-25869贡献。)从浮点数和小数创建
fractions.Fraction
实例现在快了 2 到 3 倍。(由Serhiy Storchaka在bpo-25971贡献。)
构建和 C API 更改¶
Python 现在在构建工具链时需要一些 C99 支持。最值得注意的是,Python 现在使用标准整数类型和宏,而不是像
PY_LONG_LONG
这样的自定义宏。有关更多信息,请参阅 PEP 7 和 bpo-17884。使用 Android NDK 和 Android API 级别设置为 21 (Android 5.0 Lollipop) 或更高版本交叉编译 CPython 成功运行。虽然 Android 尚未成为受支持的平台,但 Python 测试套件在 Android 模拟器上运行,只有大约 16 个测试失败。请参阅 Android 元问题 bpo-26865。
添加了
--enable-optimizations
配置标志。启用它将激活昂贵的优化,例如 PGO。(英特尔的Alecsandru Patrascu在bpo-26359中贡献的原始补丁。)现在,当调用
PYMEM_DOMAIN_OBJ
(例如:PyObject_Malloc()
)和PYMEM_DOMAIN_MEM
(例如:PyMem_Malloc()
)域的分配器函数时,必须持有 GIL。新的
Py_FinalizeEx()
API,指示刷新缓冲数据是否失败。(由Martin Panter在bpo-5319贡献。)PyArg_ParseTupleAndKeywords()
现在支持 仅位置参数。仅位置参数由空名称定义。(由Serhiy Storchaka在bpo-26282贡献)。PyTraceback_Print
方法现在将重复行的长序列缩写为"[Previous line repeated {count} more times]"
。(由Emanuel Barry在bpo-26823贡献。)新的
PyErr_SetImportErrorSubclass()
函数允许指定ImportError
的子类以引发。(由Eric Snow在bpo-15767贡献。)新的
PyErr_ResourceWarning()
函数可用于生成ResourceWarning
,提供资源分配的来源。(由Victor Stinner在bpo-26567贡献。)新的
PyOS_FSPath()
函数返回 类路径对象 的文件系统表示。(由Brett Cannon在bpo-27186贡献。)PyUnicode_FSConverter()
和PyUnicode_FSDecoder()
函数现在将接受 类路径对象。
其他改进¶
当
--version
(短形式:-V
) 被提供两次时,Python 会打印sys.version
以获取详细信息。$ ./python -VV Python 3.6.0b4+ (3.6:223967b49e49+, Nov 21 2016, 20:55:04) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
已弃用¶
新关键字¶
async
和 await
不建议用作变量、类、函数或模块名称。它们由 Python 3.5 中的 PEP 492 引入,将在 Python 3.7 中成为正式关键字。从 Python 3.6 开始,使用 async
或 await
作为名称将生成 DeprecationWarning
。
已弃用的 Python 行为¶
在生成器内部引发 StopIteration
异常现在会生成 DeprecationWarning
,并将在 Python 3.7 中触发 RuntimeError
。详见 PEP 479:更改生成器内部的 StopIteration 处理方式。
__aiter__()
方法现在期望直接返回一个异步迭代器,而不是像以前那样返回一个可等待对象。执行前者将触发 DeprecationWarning
。向后兼容性将在 Python 3.7 中移除。(由Yury Selivanov在bpo-27243贡献。)
不是有效转义序列的反斜杠字符对现在会生成 DeprecationWarning
。虽然这最终会变成 SyntaxError
,但这不会在几个 Python 版本内发生。(由Emanuel Barry在bpo-27364贡献。)
执行相对导入时,当 __spec__
或 __package__
未定义时,回退到调用模块的 __name__
和 __path__
现在会引发 ImportWarning
。(由Rose Ames在bpo-25791贡献。)
已弃用的 Python 模块、函数和方法¶
asynchat¶
asyncore¶
dbm¶
与其他 dbm
实现不同,dbm.dumb
模块以 'rw'
模式创建数据库,并允许修改以 'r'
模式打开的数据库。此行为现已弃用,并将在 3.8 版中移除。(由Serhiy Storchaka在bpo-21708贡献。)
distutils¶
distutils.Distribution
构造函数中未文档化的 extra_path
参数现在被视为已弃用,如果设置,将引发警告。对该参数的支持将在未来的 Python 版本中移除。详见 bpo-27919。
grp¶
getgrgid()
中对非整数参数的支持已弃用。(由Serhiy Storchaka在bpo-26129贡献。)
importlib¶
importlib.machinery.SourceFileLoader.load_module()
和 importlib.machinery.SourcelessFileLoader.load_module()
方法现已弃用。它们是 importlib
中 importlib.abc.Loader.load_module()
仅存的实现,在之前的 Python 版本中尚未被弃用,取而代之的是 importlib.abc.Loader.exec_module()
。
importlib.machinery.WindowsRegistryFinder
类现已弃用。截至 3.6.0 版本,它默认仍被添加到 sys.meta_path
(在 Windows 上),但这在未来的版本中可能会改变。
os¶
在 os
函数、compile()
和类似函数中,将一般 bytes-like objects 作为路径的未文档化支持现已弃用。(由 Serhiy Storchaka 在 bpo-25791 和 bpo-26754 中贡献。)
re¶
正则表达式中间的内联标志 (?letters)
的支持已弃用,并将在未来的 Python 版本中移除。正则表达式开头的标志仍然允许。(由 Serhiy Storchaka 在 bpo-22493 中贡献。)
ssl¶
OpenSSL 0.9.8, 1.0.0 和 1.0.1 已弃用,不再受支持。未来,ssl
模块将至少需要 OpenSSL 1.0.2 或 1.1.0。
ftplib
、http.client
、imaplib
、poplib
和 smtplib
中与 SSL 相关的参数,如 certfile
、keyfile
和 check_hostname
,已弃用,取而代之的是 context
。(由 Christian Heimes 在 bpo-28022 中贡献。)
ssl
模块的几个协议和函数现已弃用。某些功能在未来的 OpenSSL 版本中将不再可用。其他功能则因偏好不同的 API 而弃用。(由 Christian Heimes 在 bpo-28022 和 bpo-26470 中贡献。)
tkinter¶
tkinter.tix
模块现已弃用。tkinter
用户应改为使用 tkinter.ttk
。
venv¶
pyvenv
脚本已弃用,取而代之的是 python3 -m venv
。这可以防止 pyvenv
与哪个 Python 解释器关联以及虚拟环境将使用哪个 Python 解释器造成混淆。(由 Brett Cannon 在 bpo-25154 中贡献。)
xml¶
为了缓解 DTD 和外部实体检索问题,
xml.dom.minidom
和xml.sax
模块默认不再处理外部实体。(由 Christian Heimes 在 gh-61441 中贡献。)
已弃用的 C API 函数和类型¶
未文档化的函数 PyUnicode_AsEncodedObject()
、PyUnicode_AsDecodedObject()
、PyUnicode_AsEncodedUnicode()
和 PyUnicode_AsDecodedUnicode()
现已弃用。请改用通用基于编解码器的 API。
弃用的构建选项¶
在非 macOS 的 UNIX 平台上,--with-system-ffi
配置标志现在默认为开启。可以通过使用 --without-system-ffi
禁用它,但使用此标志已弃用,并且在 Python 3.7 中将不被接受。macOS 不受此更改的影响。请注意,许多操作系统发行商在构建其系统 Python 时已使用 --with-system-ffi
标志。
已移除¶
API 和功能移除¶
正则表达式中由
'\'
和 ASCII 字母组成的未知转义序列现在将导致错误。在re.sub()
的替换模板中,它们仍然允许,但已弃用。re.LOCALE
标志现在只能与二进制模式一起使用。inspect.getmoduleinfo()
已移除(自 CPython 3.3 起已弃用)。应使用inspect.getmodulename()
来获取给定路径的模块名称。(由 Yury Selivanov 在 bpo-13248 中贡献。)traceback.Ignore
类以及traceback.usage
、traceback.modname
、traceback.fullmodname
、traceback.find_lines_from_code
、traceback.find_lines
、traceback.find_strings
、traceback.find_executable_lines
方法已从traceback
模块中移除。它们是自 Python 3.2 以来已弃用的未文档化方法,并且等效功能可通过私有方法获得。tkinter
小部件类中的tk_menuBar()
和tk_bindForTraversal()
虚拟方法已移除(相应的 Tk 命令自 Tk 4.0 起已过时)。zipfile.ZipFile
类的open()
方法不再支持'U'
模式(自 Python 3.4 起已弃用)。在 通用换行符 模式下读取压缩文本文件,请使用io.TextIOWrapper
。未文档化的
IN
、CDROM
、DLFCN
、TYPES
、CDIO
和STROPTS
模块已移除。它们曾位于平台特定的Lib/plat-*/
目录中,但长期过时、跨平台可用性不一致且无人维护。创建这些模块的脚本仍然可以在源代码分发中的 Tools/scripts/h2py.py 找到。已弃用的
asynchat.fifo
类已移除。
移植到 Python 3.6¶
本节列出了前面描述过的变更以及其他可能需要修改代码的 bug 修复。
“python” 命令行为的更改¶
通过定义
COUNT_ALLOCS
、SHOW_ALLOC_COUNT
或SHOW_TRACK_COUNT
宏构建的特殊 Python 的输出现在默认关闭。可以使用-X showalloccount
选项重新启用。它现在输出到stderr
而不是stdout
。(由 Serhiy Storchaka 在 bpo-23034 中贡献。)
Python API 的变化¶
open()
将不再允许将'U'
模式标志与'+'
组合使用。(由 Jeff Balogh 和 John O’Connor 在 bpo-2091 中贡献。)sqlite3
不再在 DDL 语句之前隐式提交打开的事务。在 Linux 上,
os.urandom()
现在会阻塞,直到系统 urandom 熵池初始化完毕,以提高安全性。当定义了
importlib.abc.Loader.exec_module()
时,也必须定义importlib.abc.Loader.create_module()
。PyErr_SetImportError()
现在在其 msg 参数未设置时抛出TypeError
。之前只返回NULL
。代码对象的
co_lnotab
属性的格式已更改,以支持负行号增量。默认情况下,Python 不会发出具有负行号增量的字节码。使用frame.f_lineno
、PyFrame_GetLineNumber()
或PyCode_Addr2Line()
的函数不受影响。直接解码co_lnotab
的函数应更新以使用带符号的 8 位整数类型作为行号增量,但这仅在支持使用负行号增量的应用程序时才需要。有关co_lnotab
格式及其解码方式,请参阅Objects/lnotab_notes.txt
,有关理由,请参阅 PEP 511。compileall
模块中的函数现在返回布尔值而不是1
或0
,分别表示成功或失败。由于布尔值是整数的子类,因此这只会在您对1
或0
进行身份检查时才是一个问题。请参阅 bpo-25768。读取
urllib.parse.urlsplit()
和urlparse()
结果的port
属性现在对于超出范围的值会引发ValueError
,而不是返回None
。参见 bpo-20059。imp
模块现在会引发DeprecationWarning
而不是PendingDeprecationWarning
。以下模块已将其缺少的 API 添加到它们的
__all__
属性中,以匹配文档化的 API:calendar
、cgi
、csv
、ElementTree
、enum
、fileinput
、ftplib
、logging
、mailbox
、mimetypes
、optparse
、plistlib
、smtpd
、subprocess
、tarfile
、threading
和wave
。这意味着当使用import *
时,它们将导出新的符号。(由 Joel Taddei 和 Jacek Kołodziej 在 bpo-23883 中贡献。)执行相对导入时,如果
__package__
与__spec__.parent
不相等,则会引发ImportWarning
。(由 Brett Cannon 在 bpo-25791 中贡献。)当执行相对导入且没有已知父包时,将引发
ImportError
。以前可能会引发SystemError
。(由 Brett Cannon 在 bpo-18018 中贡献。)基于
socketserver
模块的服务器,包括那些在http.server
、xmlrpc.server
和wsgiref.simple_server
中定义的服务器,现在只捕获派生自Exception
的异常。因此,如果请求处理程序引发像SystemExit
或KeyboardInterrupt
这样的异常,handle_error()
将不再被调用,并且异常将停止单线程服务器。(由 Martin Panter 在 bpo-23430 中贡献。)spwd.getspnam()
现在如果用户没有权限,会引发PermissionError
而不是KeyError
。socket.socket.close()
方法现在在底层系统调用报告错误(例如EBADF
)时会引发异常。(由 Martin Panter 在 bpo-26685 中贡献。)smtpd.SMTPChannel
和smtpd.SMTPServer
构造函数的 decode_data 参数现在默认为False
。这意味着传递给process_message()
的参数现在默认是一个字节对象,并且process_message()
将传递关键字参数。已经根据 3.5 版本生成的弃用警告进行更新的代码将不受影响。json
模块中dump()
、dumps()
、load()
和loads()
函数以及JSONEncoder
和JSONDecoder
类构造函数的所有可选参数现在都是仅限关键字的。(由 Serhiy Storchaka 在 bpo-18726 中贡献。)type
的子类,如果不覆盖type.__new__
,可能无法再使用单参数形式来获取对象的类型。作为 PEP 487 的一部分,传递给
type
的关键字参数(除了元类提示metaclass
)的处理现在始终委托给object.__init_subclass__()
。这意味着type.__new__
和type.__init__
现在都接受任意关键字参数,但object.__init_subclass__()
(它从type.__new__
调用)默认会拒绝它们。接受额外关键字参数的自定义元类需要相应地调整它们对type.__new__
的调用(无论是直接调用还是通过super
调用)。在
distutils.command.sdist.sdist
中,default_format
属性已移除,不再生效。相反,gzipped tarfile 格式在所有平台上都是默认格式,不再进行平台特定的选择。在 Windows 上构建分发版且需要 zip 分发版的环境中,请使用包含以下内容的setup.cfg
文件配置项目:[sdist] formats=zip
此行为也已通过 Setuptools 26.0.0 回溯到早期 Python 版本。
在
urllib.request
模块和http.client.HTTPConnection.request()
方法中,如果未指定 Content-Length 头部字段且请求体是文件对象,则现在会使用 HTTP 1.1 分块编码发送。如果文件对象必须发送到 HTTP 1.0 服务器,则现在必须由调用者指定 Content-Length 值。(由 Demian Brecht 和 Rolf Krahl 贡献,Martin Panter 在 bpo-12319 中进行了调整。)DictReader
现在返回OrderedDict
类型的行。(由 Steve Holden 在 bpo-27842 中贡献。)如果平台不支持
crypt.METHOD_CRYPT
,则不再将其添加到crypt.methods
。(由 Victor Stinner 在 bpo-25287 中贡献。)namedtuple()
的 verbose 和 rename 参数现在仅限关键字。(由 Raymond Hettinger 在 bpo-25628 中贡献。)在 Linux 上,
ctypes.util.find_library()
现在会在LD_LIBRARY_PATH
中查找共享库。(由 Vinay Sajip 在 bpo-9998 中贡献。)imaplib.IMAP4
类现在处理从服务器发送的消息中包含']'
字符的标志,以提高实际兼容性。(由 Lita Cho 在 bpo-21815 中贡献。)mmap.mmap.write()
函数现在像其他写入方法一样返回写入的字节数。(由 Jakub Stasiak 在 bpo-26335 中贡献。)pkgutil.iter_modules()
和pkgutil.walk_packages()
函数现在返回ModuleInfo
命名元组。(由 Ramchandra Apte 在 bpo-17211 中贡献。)re.sub()
现在即使在字符串中未找到模式,也会对替换模板中无效的数字组引用引发错误。无效组引用的错误消息现在包含组索引和引用的位置。(由 SilentGhost 和 Serhiy Storchaka 在 bpo-25953 中贡献。)zipfile.ZipFile
现在将对无法识别的压缩值引发NotImplementedError
。以前会引发一个普通的RuntimeError
。此外,在已关闭的 ZipFile 上调用ZipFile
方法或在以'r'
模式创建的 ZipFile 上调用write()
方法将引发ValueError
。以前,在这些情况下会引发RuntimeError
。当自定义元类与零参数
super()
或从方法到隐式__class__
闭包变量的直接引用结合使用时,隐式__classcell__
命名空间条目现在必须传递给type.__new__
进行初始化。否则,在 Python 3.6 中将导致DeprecationWarning
,在 Python 3.8 中将导致RuntimeError
。随着
ModuleNotFoundError
的引入,导入系统的消费者可能会开始期望导入系统替换在适当的时候引发更具体的异常,而不是不那么具体的ImportError
。为了提供与此类消费者未来的兼容性,完全替换__import__()
的替代导入系统的实现者需要更新其实现,以便在完全找不到模块时引发新的子类。符合默认导入系统插件的实现者不需要进行任何更改,因为默认导入系统将在适当的时候引发新的子类。
C API 的变化¶
PyMem_Malloc()
分配器系列现在使用 pymalloc 分配器 而不是系统malloc()
。在不持有 GIL 的情况下调用PyMem_Malloc()
的应用程序现在可能会崩溃。将PYTHONMALLOC
环境变量设置为debug
以验证应用程序中内存分配器的使用。请参阅 bpo-26249。
CPython 字节码变更¶
Python 3.6 中的字节码 有几个重大更改。
Python 解释器现在使用 16 位字码而不是字节码。(由 Demur Rumed 在 Serhiy Storchaka 和 Victor Stinner 的输入和审阅下在 bpo-26647 和 bpo-28050 中贡献。)
新的
FORMAT_VALUE
和BUILD_STRING
操作码是格式化字符串字面量实现的一部分。(由 Eric Smith 在 bpo-25483 中,以及 Serhiy Storchaka 在 bpo-27078 中贡献。)新的
BUILD_CONST_KEY_MAP
操作码用于优化具有常量键的字典的创建。(由 Serhiy Storchaka 在 bpo-27140 中贡献。)函数调用操作码已进行大量重写,以提高性能并简化实现。
MAKE_FUNCTION
、CALL_FUNCTION
、CALL_FUNCTION_KW
和BUILD_MAP_UNPACK_WITH_CALL
操作码已修改,添加了新的CALL_FUNCTION_EX
和BUILD_TUPLE_UNPACK_WITH_CALL
,并移除了CALL_FUNCTION_VAR
、CALL_FUNCTION_VAR_KW
和MAKE_CLOSURE
操作码。(由 Demur Rumed 在 bpo-27095 中,以及 Serhiy Storchaka 在 bpo-27213 和 bpo-28257 中贡献。)已添加新的
SETUP_ANNOTATIONS
和STORE_ANNOTATION
操作码以支持新的变量注解语法。(由 Ivan Levkivskyi 在 bpo-27985 中贡献。)
Python 3.6.2 中的显著变化¶
新的 make regen-all
构建目标¶
为了简化交叉编译,并确保 CPython 可以可靠地编译而无需现有 Python 版本,基于 autotools 的构建系统不再尝试根据文件修改时间隐式重新编译生成的文件。
相反,已添加新的 make regen-all
命令,以便在需要时(例如,在基于预生成版本构建了初始 Python 版本之后)强制重新生成这些文件。
还定义了更具选择性的重新生成目标 - 有关详细信息,请参阅 Makefile.pre.in。
(由 Victor Stinner 在 bpo-23404 中贡献。)
在 3.6.2 版本中新增。
移除 make touch
构建目标¶
以前用于通过更新生成文件修改时间来请求隐式重新生成生成文件的 make touch
构建目标已移除。
它已被新的 make regen-all
目标取代。
(由 Victor Stinner 在 bpo-23404 中贡献。)
在 3.6.2 版本中更改。
Python 3.6.4 中的显著变化¶
作为公共 API 一部分的 PyExc_RecursionErrorInst
单例已被移除,因为其成员从未被清除,可能导致解释器终结期间发生段错误。(由 Xavier de Gaye 在 bpo-22898 和 bpo-30697 中贡献。)
Python 3.6.5 中的显著变化¶
locale.localeconv()
函数现在在某些情况下临时将 LC_CTYPE
区域设置更改为 LC_NUMERIC
区域设置。(由 Victor Stinner 在 bpo-31900 中贡献。)
Python 3.6.7 中的显著变化¶
xml.dom.minidom
和 xml.sax
模块默认不再处理外部实体。另请参阅 gh-61441。
在 3.6.7 中,tokenize
模块现在在提供没有尾随换行符的输入时,隐式地发出一个 NEWLINE
令牌。此行为现在与 C tokenizer 在内部执行的操作匹配。(由 Ammar Askar 在 bpo-33899 中贡献。)
Python 3.6.10 中的显著变化¶
由于重大的安全问题,不再支持 asyncio.loop.create_datagram_endpoint()
的 reuse_address 参数。这是由于 SO_REUSEADDR
套接字选项在 UDP 中的行为。有关更多详细信息,请参见 loop.create_datagram_endpoint()
的文档。(由 Kyle Stanley、Antoine Pitrou 和 Yury Selivanov 在 bpo-37228 中贡献。)
Python 3.6.13 中的显著变化¶
早期的 Python 版本允许在 urllib.parse.parse_qs()
和 urllib.parse.parse_qsl()
中同时使用 ;
和 &
作为查询参数分隔符。出于安全考虑,并为了符合更新的 W3C 建议,现在已更改为只允许使用单个分隔符键,默认值为 &
。此更改也影响 cgi.parse()
和 cgi.parse_multipart()
,因为它们内部使用了受影响的函数。有关更多详细信息,请参阅它们各自的文档。(由 Adam Goldschmidt、Senthil Kumaran 和 Ken Jin 在 bpo-42967 中贡献。)
Python 3.6.14 中的显著变化¶
一项安全修复程序改变了 ftplib.FTP
的行为,使其在建立被动数据通道时不再信任远程服务器发送的 IPv4 地址。我们改为重用 FTP 服务器的 IP 地址。对于需要旧行为的特殊代码,请将 FTP 实例上的 trust_server_pasv_ipv4_address
属性设置为 True
。(参见 gh-87451)
URL 中包含换行符或制表符可能导致某些形式的攻击。根据更新 RFC 3986 的 WHATWG 规范,解析器 urllib.parse()
从 URL 中删除 ASCII 换行符 \n
、\r
和制表符 \t
,以防止此类攻击。移除的字符由新的模块级别变量 urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE
控制。(请参阅 gh-88048)