快速学会使用Python3.12的新特性

一、 PEP 695: 类型形参语法的革新

PEP 695 在 Python 3.12 中引入了一种新颖且更为清晰的方式来定义泛型类和函数,旨在提升类型参数的明确性和简洁性。这个提案不仅改善了类型系统的可读性,还增强了其功能性。以下是这些变化的详细概述:

1. 泛型类和函数的新定义方式

在 PEP 484 的基础上,PEP 695 引入了一种更紧凑、明确的泛型类和函数的创建方法。与以前的详细语法相比,新方法更简洁,且类型参数的范围更加明确。例如:

def max[T](args: Iterable[T]) -> T:...class list[T]:def __getitem__(self, index: int, /) -> T:...def append(self, element: T) -> None:...
2. 类型别名的新声明方式

PEP 695 还引入了使用 type 语句声明类型别名的方法。这些别名可以是普通类型或泛型类型,为类型注解提供了更多的灵活性。例如:

type Point = tuple[float, float]
type Point[T] = tuple[T, T]
3. 新的类型参数声明

这个提案允许声明各种新的类型参数,例如 TypeVarTupleParamSpec,以及带边界或约束的 TypeVar。这些新的类型参数扩展了 Python 类型系统的表达能力。例如:

type IntFunc[**P] = Callable[P, int]  # ParamSpec
type LabeledTuple[*Ts] = tuple[str, *Ts]  # TypeVarTuple
type HashableSequence[T: Hashable] = Sequence[T]  # TypeVar with bound
type IntOrStrSequence[T: (int, str)] = Sequence[T]  # TypeVar with constraints
4. 惰性求值和作用域

PEP 695 强调,类型别名的值和类型变量的边界、约束仅在需要时进行求值,即实现了惰性求值。这意味着类型别名可以引用稍后在文件中定义的其他类型。同时,通过类型参数列表声明的类型参数在其声明的作用域内及嵌套作用域内可见,但在外部作用域不可见。

5. 标注作用域的引入

为了支持这些作用域定义,PEP 695 引入了一种新的作用域——标注作用域。这种作用域在很大程度上类似于函数作用域,但其与封闭类作用域的交互方式有所不同。在未来的 Python 3.13 中,标注也将在这种新的标注作用域中进行求值。

通过这些改进,PEP 695 不仅提高了类型注解的可读性和易用性,还为 Python 类型系统带来了更强的表达力和灵活性。更多细节可以在 PEP 695 中找到。

二、 PEP 701: 对 f-字符串的增强和放宽限制

Python 3.12 中的 PEP 701 带来了对 f-字符串(格式化字符串)的显著改进,放宽了之前的一些限制,使其更加强大和灵活。以下是这些改进的详细介绍:

1. 引号的重用

在 Python 3.11 及之前版本中,f-字符串中不能使用与其本身相同的引号,否则会引发 SyntaxError。例如,如果 f-字符串用单引号标记,则表达式部分不能包含单引号。这种限制在 Python 3.12 中被取消,现在你可以在 f-字符串的表达式部分自由使用任何类型的引号。例如:

songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
f"This is the playlist: {', '.join(songs)}"
# 输出: 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'

此外,这项改变使得 f-字符串可以更灵活地嵌套使用,如:

f"{f'{f"{f"{f"{1+1}"}"}"}'}"
# 输出: '2'
2. 多行表达式和注释

在以前的版本中,f-字符串的表达式必须在一行内完成,这对于复杂的表达式或需要注释的情况不太方便。Python 3.12 允许 f-字符串表达式跨越多行,并支持在其中添加注释,使代码更易于理解和维护。例如:

f"""This is the playlist: {', '.join(['Take me back to Eden',  # My, my, those eyes like fire'Alkaline',              # Not acid nor alkaline'Ascensionism'           # Take to the broken skies at last
])}"""
# 输出: 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
3. 反斜杠和 Unicode 字符

在 Python 3.12 之前,f-字符串表达式中不能包含任何反斜杠 (\) 字符,这限制了 Unicode 转义序列的使用。现在,你可以在 f-字符串表达式中使用反斜杠和 Unicode 转义序列。例如:

songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
print(f"This is the playlist: {'\n'.join(songs)}")
# 输出: 
# This is the playlist: Take me back to Eden
# Alkaline
# Ascensionismprint(f"This is the playlist: {'\N{BLACK HEART SUIT}'.join(songs)}")
# 输出: 'This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism'

总的来说,PEP 701 为 Python 开发者提供了更大的灵活性和表达能力,尤其是在处理复杂的字符串格式化时。这些改进使得 f-字符串成为一个更加强大和便捷的工具。

4. f-字符串错误消息的变化

在 Python 3.11 及以前版本中,f-字符串的错误消息往往缺乏精确性。例如,在遇到语法错误时,Python 3.11 可能会给出如下错误提示:

my_string = f"{x z y}" + f"{1 + 1}"
# 错误输出:
#   File "<stdin>", line 1
#     (x z y)
#      ^^^
# SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?

在这种情况下,错误消息不仅没有准确指出错误的具体位置,而且错误的表达式被不自然地用括号括起来。

Python 3.12 使用 PEG 解析器来解析 f-字符串,使得错误消息变得更加精确和有用。现在,当遇到类似的语法错误时,错误消息会精确指出错误所在的位置,并显示整行代码:

my_string = f"{x z y}" + f"{1 + 1}"
# 错误输出:
#   File "<stdin>", line 1
#     my_string = f"{x z y}" + f"{1 + 1}"
#                    ^^^
# SyntaxError: invalid syntax. Perhaps you forgot a comma?

四、PEP 684: 引入解释器级 GIL 提高 Python 多核性能

PEP 684 在 Python 3.12 中引入了一个重要的更新——解释器级的全局解释器锁(GIL)。这项改进旨在解决 Python 在多核 CPU 性能方面的一些限制,为 Python 带来更好的并行计算能力。

1. 解释器级 GIL 的概念

GIL 是 Python 解释器中一个众所周知的特性,它在任何时候只允许一个线程执行 Python 字节码。虽然这简化了 CPython 解释器的设计并提高了单线程程序的性能,但它也限制了 Python 程序在多核处理器上的并行执行能力。

PEP 684 通过引入解释器级 GIL,使得可以创建带有独立 GIL 的子解释器。这意味着每个子解释器可以在其自己的线程中独立运行,从而更好地利用多核 CPU 的性能。

2. 如何创建带有独立 GIL 的解释器

目前,这个特性只能通过 C-API 实现,预计在 Python 3.13 中将添加相应的 Python API。使用 Py_NewInterpreterFromConfig() 函数可以创建一个具有独立 GIL 的新解释器。以下是一个示例代码:

PyInterpreterConfig config = {.check_multi_interp_extensions = 1,.gil = PyInterpreterConfig_OWN_GIL,
};
PyThreadState *tstate = NULL;
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
if (PyStatus_Exception(status)) {return -1;
}
// 新解释器现在在当前线程中激活
3. 示例和进一步的应用

更多关于如何使用 C-API 来操作子解释器和解释器级 GIL 的示例可以在 Modules/_xxsubinterpretersmodule.c 中找到。

总体而言,PEP 684 的引入为 Python 的并行处理和多核性能优化提供了一个重要的步骤,使 Python 在多核处理器上的应用变得更加高效。这一改进由 Eric Snow 贡献,并在 gh-104210 等项目中得以实现。

五、 PEP 669: 为 CPython 引入低影响监控机制

PEP 669 在 Python 3.12 中引入了一个为 CPython 设计的新 API,用于实现低影响的性能监控。这一提案的核心在于为性能分析器、调试器和其他监控工具提供了一个高效且对程序性能影响小的监控方式。

1.新 API 的特点和优势
  1. 广泛的事件覆盖:该 API 能监控包括函数调用、返回、代码行执行、异常处理和跳转等在内的多种事件,为开发者提供全面的性能分析视角。

  2. 精确的性能开销控制:PEP 669 允许开发者只对他们需要监控的事件付出性能开销。这种选择性监控大大降低了对程序性能的影响,尤其是在生产环境中。

  3. 近零开销的调试和覆盖工具支持:通过这个 API,开发者可以使用几乎不影响程序性能的调试器和代码覆盖工具,这在以往的 Python 版本中是难以实现的。

2. 使用 sys.monitoring 模块

这个新引入的 sys.monitoring 模块提供了访问和控制事件监控的接口。通过这个模块,开发者可以注册监控事件、控制监控的粒度和范围,以及收集和分析性能数据。具体使用方法和 API 文档可以在 sys.monitoring 中找到。

六、 PEP 688: 在 Python 中使缓冲区协议更易于访问

PEP 688 为 Python 3.12 带来了对缓冲区协议的重要改进,使得在 Python 代码中使用和实现缓冲区协议变得更加直接和易于管理。

1. 缓冲区协议的 Python 实现

缓冲区协议(buffer protocol)在 Python 中主要用于提供一种访问对象内存表示的机制。这个协议常见于需要高性能数据处理的场景,比如在处理大量数据或进行科学计算时。

PEP 688 引入了以下关键特性:

  1. __buffer__() 方法: 类通过实现 __buffer__() 方法可以作为缓冲区类型使用。这允许自定义类直接支持缓冲区协议,从而与 Python 的内置缓冲区类型(如字节串和数组)一样,可以更有效地处理数据。

  2. collections.abc.Buffer 抽象基类: 这个新引入的抽象基类定义了缓冲区对象应有的基本行为和接口。通过实现这个类,开发者可以确保他们的自定义缓冲区类型符合预期的标准,从而提高代码的可维护性和可读性。

  3. inspect.BufferFlags 枚举: 这个新的枚举提供了一组标志,用于自定义缓冲区的创建过程。这些标志让开发者能够更精确地控制缓冲区的行为,如只读或只写访问,以及缓冲区的其他属性。

2. 应用和好处

这些改进使得缓冲区协议在 Python 中更易于访问和使用,特别是对于需要高效数据处理的应用。它们还提高了与缓冲区相关的代码的可读性和可维护性,使得开发者能够更容易地实现和使用复杂的内存管理逻辑。这对于科学计算、数据分析、图像处理等领域的 Python 开发者来说,是一个重要的步骤。

七、 Python 3.12 更新:改进的错误消息和类型提示特性

Python 3.12 版本中包含了对错误消息和类型提示的重要改进,这些更新旨在提高代码的可读性和易用性。

1. 改进的错误消息
  1. 更明确的 NameError 提示:

    • 当引发 NameError 并传播到最高层级时,如果与标准库中的模块名称相关,错误消息会建议可能的导入。
    • 示例:
      >>> sys.version_info
      NameError: name 'sys' is not defined. Did you forget to import 'sys'?
      
  2. 针对实例的 NameError 改进:

    • 如果在类方法中出现 NameError,且实例具有与异常中名称相同的属性,则错误建议会包括 self.<NAME>
    • 示例:
      class A:def __init__(self):self.blech = 1def foo(self):somethin = blechA().foo()
      # NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
      
  3. 改进的 SyntaxError:

    • 当用户错误地使用 import x from y 语法时,会提示正确的 from y import x 形式。
    • 示例:
      >>> import a.y.z from b.y.z
      SyntaxError: Did you mean to use 'from ... import ...' instead?
      
  4. 更有帮助的 ImportError:

    • 如果尝试从模块导入不存在的名称时,将会根据模块中的可用名称提出建议。
    • 示例:
      >>> from collections import chainmap
      ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
      
2. 类型的新增特性
  1. PEP 692: TypedDict 的应用:

    • 允许使用 TypedDict 来更精确地注释 **kwargs
    • 示例:
      from typing import TypedDict, Unpackclass Movie(TypedDict):name: stryear: intdef foo(**kwargs: Unpack[Movie]):...
      
  2. PEP 698: typing.override 装饰器:

    • 这个新装饰器指示方法旨在重写超类中的方法,帮助捕获错误。
    • 示例:
      from typing import overrideclass Base:def get_color(self) -> str:return "blue"class GoodChild(Base):@overridedef get_color(self) -> str:return "yellow"class BadChild(Base):@overridedef get_colour(self) -> str:return "red"
      # 'BadChild.get_colour' 引发类型检查器错误,因为它没有重写 'Base.get_color'
      

这些改进不仅提升了 Python 的错误消息的准确性和可理解性,还增强了类型提示的表达能力,使得 Python 代码更加健壮和易于维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/164519.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(四)C语言之符号常量概述

&#xff08;四&#xff09;C语言之符号常量概述 一、符号常量概述 一、符号常量概述 在程序中使用像300,20等这样的等类似的“幻数”不是一个好的习惯&#xff0c;它们无法向阅读该程序的人提供更多有用的信息&#xff0c;从而使得修改程序变得困难。处理这种幻数的一种方法是…

unreal 指定windows SDK

路径 &#xff1a; “C:\Users\Administrator\AppData\Roaming\Unreal Engine\UnrealBuildTool\BuildConfiguration.xml” 在Configuration中添加 <WindowsPlatform><WindowsSdkVersion>10.0.20348.0</WindowsSdkVersion></WindowsPlatform>示例&…

R数据分析:集成学习方法之随机生存森林的原理和做法,实例解析

很久很久以前给大家写过决策树&#xff0c;非常简单明了的算法。今天给大家写随机&#xff08;生存&#xff09;森林&#xff0c;随机森林是集成了很多个决策数的集成模型。像随机森林这样将很多个基本学习器集合起来形成一个更加强大的学习器的这么一种集成思想还是非常好的。…

算法面试题:反转一个整数

题目&#xff1a;反转一个整数。例如&#xff0c;输入123&#xff0c;输出321&#xff1b;输入-456&#xff0c;输出-654。注意&#xff1a;反转后的整数在32位带符号整数范围内。 编写一个函数 reverseInteger(x: int) -> int 来实现这个功能。 答案&#xff1a; def re…

【前端】必学知识ES6 1小时学会

1.ES6概述 2.let和const的认识 3.let、const、var的区别 4.模板字符串 5.函数默认参数 6.箭头函数【重点】 ​编辑7.对象初始化简写以及案例分析 【重点】 8.对象解构 8.对象传播操作符 9.对象传播操作符案例分析 ​编辑 10.数组Map 11.数组Reduce 12.NodeJS小结 …

代码随想录算法训练营第四十四天【动态规划part06】 | 完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ

完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 题目链接&#xff1a; 题目页…

计算机毕业设计 基于Hadoop的物品租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

YOLO目标检测——泄露检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;泄露检测数据集说明&#xff1a;泄露检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;含多个类别标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、coco(json)和yo…

AES 加解密

AES 加解密 AES(Advanced Encryption Standard),又称高级加密标准,是一种对称加密算法,也是目前广泛使用的加密技术之一。其主要特点是加密速度快、安全性高、可扩展性好等。 AES 算法采用对称加密的方式,即加密和解密使用相同的密钥进行操作。密钥长度可以是 128、192…

【JavaSE】不允许你不会使用String类

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;JavaSE&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 前言&#xff1a; 一、常用方法 1.1 字符串构造 1.2 String对象的比较 &#xff08;1&#xff09;比较是否引用同一个对象 注意…

从零开始的C++(十九)

红黑树&#xff1a; 一种接近平衡的二叉树&#xff0c;平衡程度低于搜索二叉树。 特点&#xff1a; 1.根节点为黑 2.黑色结点的子结点可以是红色结点或黑色结点。 3.红色结点的子结点只能是黑色结点。 4.每个结点到其所有叶子结点的路径的黑色结点个数相同。 5.指向空的…

OmniGraffle

安装 在mac上安装OmniGraffle&#xff0c;找一个正版或者啥的都行&#xff0c;安装好后&#xff0c;可以直接在网上找一个激活码&#xff0c;然后找到软件的许可证&#xff0c;进行添加即可。 使用 新建空白页 然后图形啥的看一眼工具栏就知道了&#xff0c;颜色形状还是挺…

音视频项目—基于FFmpeg和SDL的音视频播放器解析(二十一)

介绍 在本系列&#xff0c;我打算花大篇幅讲解我的 gitee 项目音视频播放器&#xff0c;在这个项目&#xff0c;您可以学到音视频解封装&#xff0c;解码&#xff0c;SDL渲染相关的知识。您对源代码感兴趣的话&#xff0c;请查看基于FFmpeg和SDL的音视频播放器 如果您不理解本…

【C++】拷贝构造函数,析构函数详解!

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

【LeetCode】挑战100天 Day13(热题+面试经典150题)

【LeetCode】挑战100天 Day13&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-152.1 题目2.2 题解 三、面试经典 150 题-153.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

Vue3 实现elementPlus的table列宽调整和拖拽

1、需要的包 // 除了Vue和element-plus外还需要以下的包 npm install sortablejs2、具体代码如下&#xff0c;可直接粘贴运行 <template><div class"draggable-table"><el-table ref"tableRef":data"tableData.data":key"…

Java-飞翔的小鸟

前言 基于Java的飞翔小鸟游戏&#xff0c;本代码来自b站up主分享。本游戏所需的图片素材需要自己获取并下载&#xff0c;在此视频下&#xff0c;视频链接&#xff1a;【Java经典小游戏项目之飞翔的小鸟】 https://www.bilibili.com/video/BV1ou411o7br/?p10&share_source…

C#编程题分享(4)

换行输出整数问题 输⼊任意⼀个位数未知的整数&#xff0c;输出这个数每⼀位上的数字。输出的时候&#xff0c;从个位开始输出&#xff0c;每输出⼀个数字换⼀⾏。样例输⼊&#xff1a;3547 输出&#xff1a;7 换行输出 4 换行输出5 换行输出3 int n Convert.ToInt32(Conso…

【python基础(九)】文件和异常详解:使用、读取、写入、追加、保存用户的信息,以及优雅的处理异常

文章目录 一. 从文件中读取数据1. 读取整个文件2. 文件路径3. 逐行读取4. 创建一个包含文件各行内容的列表 二. 写入文件1. 写入空文件2. 写入多行3. 附加到文件 三. 异常1. 处理ZeroDivisionError异常2. 使用try-except代码块3. try-except-else ing4. 处理FileNotFoundError异…

如何在AD上创建完整的项目

首先&#xff0c;我们先安装好AD&#xff0c;这里我使用的是AD22&#xff0c;安装过程如下&#xff1a; Altium Designer 22下载安装教程-CSDN博客 Altium Designer 22是全球领先的PCB设计软件之一&#xff0c;为电路板设计师提供了一种集成的解决方案&#xff0c;旨在简化和加…