用例子看看,Python 3.12 到底更新了啥?

在前几天,python 3.12 正式发布了,那到底更新了哪些内容呢?一起来看看

改善报错信息


来自官方标准库的模块现在可以在报NameError时提示问题原因,比如

>>> sys.version_info  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
NameError: name 'sys' is not defined. Did you forget to import 'sys'?  

当实例内报NameError时也会提示问题原因,比如成员方法引用了未定义的变量,而这个变量名又和成员变量名相同时会提示用户是否忘记加self,比如

>>> class A:  
...    def __init__(self):  
...        self.blech = 1  
...  
...    def foo(self):  
...        somethin = blech  
  
>>> A().foo()  
Traceback (most recent call last):  
  File "<stdin>", line 1  
    somethin = blech  
               ^^^^^  
NameError: name 'blech' is not defined. Did you mean: 'self.blech'?  

当导入模块时importfrom写反报SyntaxError时也会提示原因,比如

>>> import a.y.z from b.y.z  
Traceback (most recent call last):  
  File "<stdin>", line 1  
    import a.y.z from b.y.z  
    ^^^^^^^^^^^^^^^^^^^^^^^  
SyntaxError: Did you mean to use 'from ... import ...' instead?  

在导入模块错误报ImportError时也会提示应该导入哪个对象,比如

python  
复制代码>>> from collections import chainmap  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?  

新功能


PEP701 f-string的语义格式化

现在f-string内的表达式可以是任何合法的Python表达式,包括反斜杠、Unicode转义、多行表达式、注释和重复使用的引号种类。

  • 重复使用的引号种类:在Python 3.12版本中,用户可以在表达式里重复使用f-string使用过的引号种类,比如这里重复使用了双引号
>>> 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'  

因为这个改动,现在Python可以内嵌多个f-string了,比如以前只能内嵌4层

>>> f"""{f'''{f'{f"{1+1}"}'}'''}"""  
'2'  

现在则没有这种限制

>>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"  
'2'  

  • 多行表达式和注释:以前在f-string中必须把表达式写在一行内,可读性不高。现在没有这种限制,并且可以包含注释。
>>> 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'  

  • 反斜杠和Unicode字符:以前在f-string中不能使用反斜杠和Unicode转义。这会使得有的Unicode字符无法在f-string中使用,现在没有这种限制了。
python  
复制代码>>> print(f"This is the playlist: {"\n".join(songs)}")  
This is the playlist: Take me back to Eden  
Alkaline  
Ascensionism  
>>> print(f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}")  
This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism  

一个有用的副作用就是现在报错的位置更精准了。比如在3.11中解释器不能告诉用户SyntaxError错误产生的位置。

>>> 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?  

现在可以获取到报错位置了。

>>> 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?  

PEP709 内联行为

现在解释器会把字典、列表和集合理解成内联行为,而不是只用一次的数据结构,这样做会让程序运行速度提升一倍。但是,迭代器并不会理解成内联行为。

译者:这部分关系到虚拟机帧栈的优化,其API对普通用户并无感知。

PEP 688 Buffer协议可以暴露给用户使用

这个提案介绍了如何让Python用户使用到buffer协议,只需要让类实现__buffer__()方法就可以把它当作Buffer类使用。

与此同时,新的collections.abc.Buffer抽象基类提供了标准的暴露buffer的方式,比如在类型注解里。在新的inspect.BufferFlags枚举可以表示自定义的buffer资源。

与类型注解相关的新功能


PEP 692 用`TypedDict`注解**kwargs类型

PEP 484 介绍了如何注解函数签名中**kwargs的类型,但是所有的**kwargs类型都一样。这份提案提供了一种更精确的类型注解方案,比如

from typing import TypedDict, Unpack  
  
class Movie(TypedDict):  
  name: str  
  year: int  
  
def foo(**kwargs: Unpack[Movie]): ...  

PEP 698 静态类型注解的override装饰器

typing模块中加入了一个新的装饰器typing.override(),它表明被它修饰的方法需要复写其父类的同名方法(译者注:类似于Java的@Overide)。它可以让类型检查该方法是否正确复写了父类的方法。

from typing import override  
  
class Base:  
  def get_color(self) -> str:  
    return "blue"  
  
class GoodChild(Base):  
  @override  # ok: overrides Base.get_color  
  def get_color(self) -> str:  
    return "yellow"  
  
class BadChild(Base):  
  @override  # type checker error: does not override Base.get_color  
  def get_colour(self) -> str:  
    return "red" 

PEP 695 参数类型语法

在PEP 484 中,Python对泛型类和方法类型注解的支持有点啰嗦且不够精确,并需要一套更直白的类型声明方案。本提案引入了一种新的、简洁的、直白的类型注解方案。

def max[T](args: Iterable[T]) -> T:  
    ...  
  
class list[T]:  
    def __getitem__(self, index: int, /) -> T:  
        ...  
  
    def append(self, element: T) -> None:  
        ...  

此外,本方案还引入了一种新type别名声明方案,并可以通过type创建一个TypeAliasType实例。

type Point = tuple[float, float]  

类型别名同样可以加入泛型。

type Point[T] = tuple[T, T]  

新的语法规则允许声明TypeVarTupleParamSpec,就像声明TypeVar一样。

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  

类型别名、范围以及限制类型只有在解释器需要的时候创建,也就是说别名可以在代码其他地方被重写。

参数类型的声明作用于声明的范围,对其外部是不生效的。举个例子,函数参数的类型注解可以作用于其派生类的方法或该类的其他地方。然而,它不能作用于模块范围内的其他地方,即使这个地方位于该类的定义的后面。具体使用方法可以参考Type parameter lists章节。

为了支持这种范围的类型注解,现在虚拟机引入了一种新的范围——注解范围(annotation scope)。在大多数情况下,这个范围等同于函数的范围,但是它会和不同的类的范围发生关联。在Python 3.13中,所有的类型注解都会在这个范围内。

其他语言改动(部分)


  • 增加了环境变量PYTHONPERFSUPPORT、命令行参数-X perf以及API

  • sys.activate_stack_trampoline()、sys.deactivate_stack_trampoline()和sys.is_stack_trampoline_active()以支持Linux优化(Python support for the Linux perf profiler)

  • 如果底层字典结构是可哈希的,那么types.MappingProxyType实例现在也是可哈希的

  • 语法分析器现在可以分析空字节

  • 现在GC只会在字节码之间的暂停点运行,而不是分配内存的时候运行。另外,GC还会在调用PyErr_CheckSignals()时运行。这样,在Python的C扩展中解释器可以执行大量的C语言代码而不去执行Python代码,以便减少GC运行的可能性。

  • 你可以在生成的数据中使用海象运算符(:=)来赋值,比如[(b := 1) for a, b.prop in some_iter]

  • slice对象现在是可哈希的,所以可以用作字典的键。

  • sum()方法现在用了新的求和算法,所以现在更精确了。

小结


以上是Python 3.12语法层面的改动。可以看出,现在Python委员会的发力点一个是类型注解,另一个是GC的使用效率。他们这么做也很好理解,这两个问题一直是为人诟病的症结。弱类型语言使得Python成为不了大型项目的开发语言,而效率低下的GC也是阻碍Python往前一步的绊脚石。

不管怎么说,Python毫无疑问是当下最热门的语言,具体会往什么方向发展,让我们拭目以待吧。

感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述
若有侵权,请联系删除
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值