Python 3.6 有什么新变化 - 新功能&新模块

PEP 498:格式化字符串文本

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 526:变量注释的语法

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:数字文字中的下划线

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 525:异步发电机

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:异步推导

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由Martin Teichmann编写和实施。

功能文档

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 487 – 类创建的更简单自定义
PEP由Martin Teichmann编写和实施。

功能文档

PEP 519:添加文件系统路径协议

文件系统路径历来表示为 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撰写。

PEP 495:本地时间消歧

在世界上大多数地方,曾经并将会有当地时钟 被移回。在那些时候,引入了间隔,其中本地 时钟在同一天显示同一时间两次。在这些情况下, 本地时钟上显示的信息(或存储在 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编写,实现 亚历山大·别洛波尔斯基。

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 字符和 提供正确读取的 str 对象到 Python 代码。,现在默认为 UTF-8 编码。sys.stdinsys.stdoutsys.stderr

此更改仅适用于使用交互式控制台的情况,不适用于 重定向文件或管道。恢复到以前的交互式行为 控制台使用,设置 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编写和实现。

新字典实现

字典类型现在使用“紧凑”表示形式 基于Raymond Hettinger的提议,该提案首先由PyPy实施。 新 dict() 的内存使用量减少了 20% 到 25% 与Python 3.5相比。

此新实现的顺序保留方面被视为 实现细节,不应依赖(这可能会在 未来,但希望在 在将语言规范更改为强制之前的一些版本的语言 所有当前和未来 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 内存分配器和安装调试挂钩。

现在可以在 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 中提供。

DTrace 和 SystemTap 探测支持

现在可以构建支持静态标记的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编写和实施。

你可能感兴趣的:(Python,python,开发语言)