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-字符串,或 格式化字符串字面量。
格式化字符串字面量以 '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
为了允许从 __init_subclass__()
实现中正确调用零参数的 super()
,自定义元类必须确保新的 __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 – 添加文件系统路径协议
由 Brett Cannon 和 Koos Zevenhoven 编写的 PEP。
PEP 495:本地时间歧义¶
在世界上大多数地区,都存在过去和将来本地时钟回拨的情况。在这些时候,会引入一些时间间隔,在这些时间间隔内,本地时钟在同一天内会两次显示相同的时间。在这些情况下,本地时钟上显示的信息(或存储在 Python datetime 实例中的信息)不足以识别特定的时间点。
PEP 495 将新的 fold 属性添加到 datetime.datetime
和 datetime.time
类的实例中,以区分本地时间相同的两个时间点
>>> 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 – 本地时间歧义
由 Alexander Belopolsky 和 Tim Peters 编写的 PEP,由 Alexander Belopolsky 实现。
PEP 529:将 Windows 文件系统编码更改为 UTF-8¶
表示文件系统路径最好使用 str (Unicode) 而不是字节。但是,在某些情况下,使用字节就足够且正确。
在 Python 3.6 之前,在 Windows 上使用字节路径可能会导致数据丢失。进行此更改后,现在 Windows 上支持使用字节来表示路径,前提是这些字节使用 sys.getfilesystemencoding()
返回的编码进行编码,现在默认为 'utf-8'
。
不使用 str 来表示路径的应用程序应使用 os.fsencode()
和 os.fsdecode()
来确保其字节得到正确编码。要恢复到以前的行为,请设置 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
由 Steve Dower 编写和实现的 PEP。
PEP 520:保留类属性定义顺序¶
类定义体中的属性具有自然的顺序:与名称在源代码中出现的顺序相同。此顺序现在保存在新类的 __dict__
属性中。
此外,有效的默认类执行命名空间(从 type.__prepare__() 返回)现在是一个保留插入顺序的映射。
另请参阅
- PEP 520 – 保留类属性定义顺序
由 Eric Snow 编写和实现的 PEP。
PEP 468:保留关键字参数顺序¶
函数签名中的 **kwargs
现在保证是一个保留插入顺序的映射。
另请参阅
- PEP 468 – 保留关键字参数顺序
由 Eric Snow 编写和实现的 PEP。
新的 dict 实现¶
dict 类型现在使用基于 Raymond Hettinger 的提案 的“紧凑”表示形式,该提案 首先由 PyPy 实现。与 Python 3.5 相比,新的 dict()
的内存使用量减少了 20% 到 25%。
这种新实现的顺序保留特性被认为是实现细节,不应依赖它(将来可能会更改,但希望在更改语言规范以强制所有当前和未来的 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()
函数。
现在还可以强制对所有 Python 内存分配使用 C 库的 malloc()
分配器,方法是使用 PYTHONMALLOC=malloc
。这在对发布模式下编译的 Python 使用 Valgrind 等外部内存调试器时很有帮助。
出错时,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 探测支持¶
现在可以构建带有 --with-dtrace
的 Python,这会为解释器中的以下事件启用静态标记
函数调用/返回
垃圾回收开始/完成
执行的代码行。
这可以用来检测生产中运行的解释器,而无需重新编译特定的 调试版本 或提供特定于应用程序的分析/调试代码。
有关更多详细信息,请参阅 使用 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 中贡献。)导入操作现在会在找不到模块时引发新的异常
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 中贡献。)当传递
StopIteration
异常的实例时,Future.set_exception
现在将引发TypeError
。(由 Chris Angelico 在 bpo-26221 中贡献。)新的
loop.connect_accepted_socket()
方法,供在 asyncio 之外接受连接但使用 asyncio 处理这些连接的服务器使用。(由 Jim Fulton 在 bpo-27392 中贡献。)TCP_NODELAY
标志现在默认设置为所有 TCP 传输。(由 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 中贡献。)
现在可以 pickle 递归 collections.deque
实例。(由 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¶
distutils.command.sdist.sdist
中已删除 default_format
属性,formats
属性的默认值设置为 ['gztar']
。尽管没有预期到,但任何依赖 default_format
存在的代码可能需要进行调整。有关更多详细信息,请参见 bpo-27819。
email¶
通过 policy 关键字启用新的电子邮件 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
和 IntFlags
。两者都用于定义可以使用按位运算符组合的常量。(由 Ethan Furman 在 bpo-23591 中贡献。)
许多标准库模块已更新为在其常量中使用 IntFlags
类。
新的 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 行)的输出会压缩为一个按钮。可以在“设置”对话框的“常规”页面的“PyShell”部分中更改 N。可以通过右键单击输出来压缩较少但可能超长的行。可以通过双击按钮将压缩的输出就地展开,或者通过右键单击按钮将其展开到剪贴板或单独的窗口中。(由 Tal Einat 在 bpo-1529353 中贡献。)
importlib¶
当无法找到模块时,导入现在会引发新的异常 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¶
有关 os
和 os.path
模块现在如何支持 路径类对象 的详细信息,请参见 PEP 519 的摘要。
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¶
现在可以使用低于协议版本 4 的 pickle 协议 来封送需要使用关键字参数调用 __new__
的对象。协议版本 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¶
通过新的 punctuation_chars 参数来控制哪些字符被视为标点符号,shlex
具有改进的 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 中贡献。)
可以使用新的 SSLSession
类将 SSL 会话从一个客户端连接复制到另一个客户端连接。TLS 会话恢复可以加速初始握手,减少延迟并提高性能(由 Christian Heimes 在 bpo-19500 中基于 Alex Warhawk 的草案贡献。)
可以使用新的 get_ciphers()
方法按密码优先级顺序获取已启用密码的列表。
所有常量和标志都已转换为 IntEnum
和 IntFlags
。(由 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 中贡献)。
time¶
现在在所有平台上都可以使用 struct_time
属性 tm_gmtoff
和 tm_zone
。
timeit¶
添加了新的 Timer.autorange()
便利方法,用于重复调用 Timer.timeit()
,以便总运行时间大于或等于 200 毫秒。(由 Steven D’Aprano 在 bpo-6422 中贡献。)
当最佳时间和最差时间之间存在较大(4 倍)差异时,timeit
现在会发出警告。(由 Serhiy Storchaka 在 bpo-23552 中贡献。)
tkinter¶
在 tkinter.Variable
类中添加了方法 trace_add()
、trace_remove()
和 trace_info()
。它们取代了使用过时的 Tcl 命令的旧方法 trace_variable()
、trace()
、trace_vdelete()
和 trace_vinfo()
,这些方法在未来版本的 Tcl 中可能无法正常工作。(由 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
模块是临时的,因此 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 请求具有文件或可迭代的 body(而不是字节对象),但没有 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()
“Object allocated at” 回溯是新的,仅当 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 倍,并减少内存占用。对于错误处理程序
surrogateescape
、ignore
和replace
,ASCII 解码器现在的速度提高了 60 倍(由 Victor Stinner 在 bpo-24870 中贡献)。对于错误处理程序
surrogateescape
,ASCII 和 Latin1 编码器现在的速度提高了 3 倍(由 Victor Stinner 在 bpo-25227 中贡献)。对于错误处理程序
ignore
、replace
、surrogateescape
和surrogatepass
,UTF-8 编码器现在的速度提高了 75 倍(由 Victor Stinner 在 bpo-25267 中贡献)。对于错误处理程序
ignore
、replace
和surrogateescape
,UTF-8 解码器现在的速度提高了 15 倍(由 Victor Stinner 在 bpo-25301 中贡献)。bytes % args
现在速度提高了 2 倍。(由 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()
和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()
函数返回 path-like object 的文件系统表示形式。(由 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
不建议用作变量、类、函数或模块名。由 PEP 492 在 Python 3.5 中引入,它们将在 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.abc.Loader.load_module()
在 importlib
中唯一剩余的实现,而在以前的 Python 版本中,这些实现尚未弃用,而是推荐使用 importlib.abc.Loader.exec_module()
。
importlib.machinery.WindowsRegistryFinder
类现在已弃用。从 3.6.0 开始,它仍然默认添加到 sys.meta_path
(在 Windows 上),但这可能会在未来的版本中更改。
os¶
现在已弃用 os
函数,compile()
和类似函数中对作为路径的通用 类字节对象 的未文档化支持。(由 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。
诸如 certfile
、keyfile
和 check_hostname
等与 SSL 相关的参数,在 ftplib
、http.client
、imaplib
、poplib
和 smtplib
中已被弃用,建议改用 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
模块中删除了traceback.Ignore
类和traceback.usage
、traceback.modname
、traceback.fullmodname
、traceback.find_lines_from_code
、traceback.find_lines
、traceback.find_strings
、traceback.find_executable_lines
方法。它们是自 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¶
本节列出了前面描述的更改和其他可能需要更改代码的错误修复。
“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()
。当 msg 参数未设置时,
PyErr_SetImportError()
现在会设置TypeError
。之前只返回NULL
。代码对象的
co_lnotab
属性的格式已更改,以支持负行号增量。默认情况下,Python 不会发出带有负行号增量的字节码。使用frame.f_lineno
、PyFrame_GetLineNumber()
或PyCode_Addr2Line()
的函数不受影响。直接解码co_lnotab
的函数应更新为对行号增量使用有符号的 8 位整数类型,但这仅在支持使用负行号增量的应用程序时才是必需的。请参阅Objects/lnotab_notes.txt
获取co_lnotab
的格式以及如何解码它,并参阅 PEP 511 了解其基本原理。compileall
模块中的函数现在返回布尔值而不是1
或0
来表示成功或失败。由于布尔值是整数的子类,因此如果您执行1
或0
的身份检查,这才会成为问题。请参阅 bpo-25768。读取
urllib.parse.urlsplit()
和urlparse()
的port
属性现在会为超出范围的值引发ValueError
,而不是返回None
。请参阅 bpo-20059。imp
模块现在引发DeprecationWarning
而不是PendingDeprecationWarning
。以下模块已在其
__all__
属性中添加了缺少的 API,以匹配文档化的 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
。如果底层系统调用报告错误(例如
EBADF
),则socket.socket.close()
方法现在会引发异常。(由 Martin Panter 在 bpo-26685 中贡献。)smtpd.SMTPChannel
和smtpd.SMTPServer
构造函数的 decode_data 参数现在默认为False
。 这意味着传递给process_message()
的参数现在默认为字节对象,并且将向process_message()
传递关键字参数。 已经根据 3.5 生成的弃用警告更新的代码不会受到影响。dump()
、dumps()
、load()
和loads()
函数以及JSONEncoder
和JSONDecoder
类构造函数在json
模块中的所有可选参数现在都是仅限关键字的。(由 Serhiy Storchaka 在 bpo-18726 中贡献。)不覆盖
type.__new__
的type
的子类可能不再使用单参数形式来获取对象的类型。作为 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.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 标记器在内部执行的操作相匹配。(由 Ammar Askar 在 bpo-33899 中贡献。)
Python 3.6.10 中的显著变化¶
由于重大的安全问题,不再支持 asyncio.loop.create_datagram_endpoint()
的 reuse_address 参数。这是由于 UDP 中套接字选项 SO_REUSEADDR
的行为。有关更多详细信息,请参阅 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)