PEP 498 引入了一种新的字符串文本:f 字符串或格式化字符串文本。
格式化字符串文本以 和 类似 str.format() 接受的格式字符串。它们包含替换 由大括号包围的田野。替换字段是表达式, 在运行时进行评估,然后使用 format() 协议进行格式化:‘f’
>>>
>>> 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 498 – 文字字符串插值。
PEP由Eric V. Smith编写和实施。
功能文档。
PEP 484 引入了函数类型注释的标准 参数,又名类型提示。这个PEP为Python添加了用于注释的语法 变量的类型包括类变量和实例变量:
primes: List[int] = []
captain: str # Note: no initial value!
class Starship:
stats: Dict[str, int] = {}
就像函数注释一样,Python 解释器不会附加任何 变量注释的特定含义,并且仅将它们存储在类或模块的属性中。annotations
与静态类型语言中的变量声明相比, 注释语法的目标是提供一种简单的方法来指定结构化 通过抽象语法树键入第三方工具和库的元数据 和属性。annotations
参见
PEP 526 – 变量注释的语法。
PEP由Ryan Gonzalez,Philip House,Ivan Levkivskyi,Lisa Roach撰写, 和圭多·范·罗苏姆。由Ivan Levkivskyi实施。
使用或将使用新语法的工具:mypy,pytype,PyCharm等。
PEP 515 增加了在数字文本中使用下划线的功能 提高了可读性。例如:
>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295
数字之间和任何基数之后都允许使用单个下划线 规范。连续的前导、尾随或多个下划线不是 允许。
字符串格式化语言现在也支持 用于表示使用下划线表示千分之一的选项 浮点表示类型和整数的分隔符 演示文稿类型 .对于整数表示类型,、 和 下划线将每 4 插入一次 数字:‘_’‘d’‘b’‘o’‘x’‘X’
>>> '{:_}'.format(1000000)
'1_000_000'
>>> '{:_x}'.format(0xFFFFFFFF)
'ffff_ffff'
参见
PEP 515 – 数字文字中的下划线
PEP由Georg Brandl和Serhiy Storchaka撰写。
PEP 492 在 Python 3.5 中引入了对本机协程和//语法的支持。Python 3.5 实现的一个显着限制 是无法使用并且在同一 函数体。在 Python 3.6 中,此限制已被取消,使其 可以定义异步生成器:asyncawaitawaityield
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 增加了对在列表、集合、字典中使用的支持 理解和生成器表达式: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编写和实施。
现在可以在不使用元类的情况下自定义子类创建。 将在基类上调用新的类方法 每当创建新的子类时: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由Martin Teichmann编写和实施。
功能文档
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 487 – 类创建的更简单自定义
PEP由Martin Teichmann编写和实施。
功能文档
文件系统路径历来表示为 str 或字节对象。这导致人们编写代码 对文件系统路径进行操作,以假定此类对象只有一个 这两种类型(表示文件描述符的 int 不算,因为这不是文件路径)。不幸的是, 假设阻止文件系统的替代对象表示 像 pathlib 这样的路径来自使用预先存在的代码, 包括 Python 的标准库。
为了解决这个问题,一个由 os 表示的新接口。路径相似已被定义。通过实现 fspath() 方法,对象发出信号,表明它 表示路径。然后,对象可以提供低级别 将文件系统路径表示为 str 或字节对象。这意味着如果对象实现了 os,则将其视为路径类。路径样或是一个 str 或字节对象 表示文件系统路径。代码可以使用 os.fspath()、os.fsdecode() 或 os.fsencode() 来显式获取类似路径的 str 和/或字节表示 对象。
内置的 open() 函数已更新为接受操作系统。PathLike 对象,以及 os 和 os.path 模块中的所有相关函数,以及大多数其他函数和 标准库中的类。操作系统。目录入门类 Pathlib 中的相关类也已更新为 实现操作系统。路径样。
希望是更新操作的基本功能 在文件系统路径上将导致第三方代码隐式 支持所有类似路径的对象,没有任何 代码更改,或者至少是非常小的代码更改(例如,在代码开头调用 os.fspath() 路径类对象)。
以下是新接口如何允许 pathlib 的一些示例。更轻松、更透明地使用 预先存在的代码:
>>>
>>> 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撰写。
在世界上大多数地方,曾经并将会有当地时钟 被移回。在那些时候,引入了间隔,其中本地 时钟在同一天显示同一时间两次。在这些情况下, 本地时钟上显示的信息(或存储在 Python 日期时间中的信息) 实例)不足以识别特定时刻。
PEP 495 将新的折叠属性添加到 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
折叠属性的值具有 所有实例的值,但表示第二个实例的实例除外 (按时间顺序)在一个模棱两可的情况下的时间时刻。0
参见
PEP 495 – 本地时间消歧
PEP由Alexander Belopolsky和Tim Peters编写,实现 亚历山大·别洛波尔斯基。
表示文件系统路径最好使用 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 字符和 提供正确读取的 str 对象到 Python 代码。,现在默认为 UTF-8 编码。sys.stdinsys.stdoutsys.stderr
此更改仅适用于使用交互式控制台的情况,不适用于 重定向文件或管道。恢复到以前的交互式行为 控制台使用,设置 PYTHONLEGACYWINDOWSSTDIO。
参见
PEP 528 – 将 Windows 控制台编码更改为 UTF-8
PEP由Steve Dower编写和实施。
类定义主体中的属性具有自然排序:相同 名称在源中的显示顺序。此订单现在是 保留在新类的 dict 属性中。
此外,有效的默认类执行命名空间(从 type.prepare() 返回)现在是一个插入顺序保留 映射。
参见
PEP 520 – 保留类属性定义顺序
PEP由Eric Snow编写和实现。
PEP 468:保留关键字参数顺序
**kwargs在函数中签名现在保证为 保留插入顺序的映射。
参见
PEP 468 – 保留关键字参数顺序
PEP由Eric Snow编写和实现。
字典类型现在使用“紧凑”表示形式 基于Raymond Hettinger的提议,该提案首先由PyPy实施。 新 dict() 的内存使用量减少了 20% 到 25% 与Python 3.5相比。
此新实现的顺序保留方面被视为 实现细节,不应依赖(这可能会在 未来,但希望在 在将语言规范更改为强制之前的一些版本的语言 所有当前和未来 Python 的顺序保持语义 实现;这也有助于保持向后兼容性 对于随机迭代顺序为 仍然有效,例如 Python 3.5)。
(由INADA Naoki在bpo-27350中提供。最初由Raymond Hettinger提出的想法。
虽然 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 环境变量允许设置 Python 内存分配器和安装调试挂钩。
现在可以在 Python 上的 Python 内存分配器上安装调试钩子 使用 在发布模式下编译。调试钩子的效果:PYTHONMALLOC=debug
新分配的内存被字节填满0xCB
释放的内存充满字节0xDB
检测 Python 内存分配器 API 的违规行为。例如,PyObject_Free() 在 PyMem_Malloc() 分配的内存块上调用。
在缓冲区启动之前检测写入(缓冲区下溢)
检测缓冲区结束后的写入(缓冲区溢出)
检查分配器时是否持有 GIL 调用PYMEM_DOMAIN_OBJ(例如:PyObject_Malloc())和PYMEM_DOMAIN_MEM(例如:PyMem_Malloc())域的函数。
检查 GIL 是否被保留也是 Python 3.6 的新功能。
请参阅 PyMem_SetupDebugHooks() 函数以了解 Python 上的调试钩子 内存分配器。
现在也可以强制使用 使用 . 的所有 Python 内存分配的 C 库。 这在使用外部存储器调试器(如 Valgrind on 上)时很有帮助 a 在发布模式下编译的 Python。malloc()PYTHONMALLOC=malloc
出错时,Python 内存分配器上的调试钩子现在使用 tracemalloc 模块来获取内存块所在的回溯 分配。
缓冲区溢出时致命错误的示例(在跟踪中存储 5 帧):python3.6 -X tracemalloc=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__
...
(由 Victor Stinner 在 bpo-26516 和 bpo-26564 中提供。
现在可以构建支持静态标记的Python。 对于解释器中的以下事件:–with-dtrace
函数调用/返回
垃圾回收开始/完成
执行的代码行。
这可用于在生产中检测运行解释器, 无需重新编译特定的调试版本或提供 特定于应用程序的分析/调试代码。
有关更多详细信息,请参阅使用 DTrace 和 SystemTap 检测 CPython。
当前的实现是在Linux和macOS上测试的。附加 将来可能会添加标记。
(由 Łukasz Langa 在 bpo-21590 中提供,基于 赫苏斯·塞亚·阿维翁、大卫·马尔科姆和尼基尔·贝内施。
对核心 Python 语言所做的一些较小的更改是:
或语句现在必须以文本方式显示 在同一范围内首次使用受影响的名称之前。 以前这是一个语法警告。globalnonlocal
现在可以设置一个特殊方法来指示相应的操作不可用。 例如,如果一个类将 iter() 设置为 ,则该类 不是可迭代的。 (由Andrew Barnert和Ivan Levkivskyi在bpo-25958中提供。NoneNone
重复回溯行的长序列现在缩写为 (有关示例,请参阅回溯)。 (由Emanuel Barry在bpo-26823中提供。“[Previous line repeated {count} more times]”
导入现在在找不到模块时引发新的异常 ModuleNotFoundError(ImportError 的子类)。法典 当前检查导入错误(在 try-except 中)仍然有效。 (由 Eric Snow 在 bpo-15767 中提供。
依赖于零参数的类方法现在可以正常工作 在类创建期间从元类方法调用时。 (由Martin Teichmann在bpo-23722中提供。super()
秘密
新secrets模块的主要目的是提供一个显而易见的方法 可靠地生成适合的加密强伪随机值 用于管理机密,例如帐户身份验证、令牌等。
警告 注意随机模块中的伪随机生成器 不应用于安全目的。在 Python 3.6+ 上使用机密,在 Python 3.5 及更早版本上使用 os.urandom()。
参见
PEP 506 – 将机密模块添加到标准库
PEP由Steven D’Aprano编写和实施。