Python3.11 新特性

简介

Python3.11 正式版在2022年10月25日发布了,主要更新了错误提示、异常处理和类型系统进行了更新

Python3.11 在性能方面较 Python3.10 快大约10%-60%,平均快大概25%

官方新特性链接 Python3.11 新特性

安装

此处主要介绍在Ubuntu下安装 Python3.11

  1. 添加deadsnakes源
    • sudo add-apt-repository ppa:deadsnakes/ppa
    • sudo apt-get update
  2. 安装 Python3.11
    • sudo apt install python3.11

报错提示

ZeroDivisionError

示例代码:print(5/0)

特性内容:3.11会在出错的位置增加了一个波浪符号

Python3.10

1
2
3
4
Traceback (most recent call last):
File "/home/project/demo.py", line 1, in <module>
print(5/0)
ZeroDivisionError: division by zero

Python3.11

1
2
3
4
5
Traceback (most recent call last):
File "/home/project/demo.py", line 1, in <module>
print(5/0)
~^~
ZeroDivisionError: division by zero

KeyError

示例代码:{'a': 1}['b']['a']

特性内容:3.11 会在出错字典下划波浪线,并且突出指出出错的key

Python3.10

1
2
3
4
Traceback (most recent call last):
File "/home/project/demo.py", line 1, in <module>
{'a': 1}['b']['a']
KeyError: 'b'

Python3.11

1
2
3
4
5
Traceback (most recent call last):
File "/home/project/demo.py", line 1, in <module>
{'a': 1}['b']['a']
~~~~~~~~^^^^^
KeyError: 'b'

IndexError

示例代码:[1, 2, 3][3]

特性内容:3.11 会在出错列表下划波浪线,并且突出指出出错的index

Python3.10

1
2
3
4
Traceback (most recent call last):
File "/home/project/demo.py", line 1, in <module>
[1, 2, 3][3]
IndexError: list index out of range

Python3.11

1
2
3
4
5
Traceback (most recent call last):
File "/home/project/demo.py", line 1, in <module>
[1, 2, 3][3]
~~~~~~~~~^^^
IndexError: list index out of range

异常组和异常上下文

异常组

在 Python3.11 中增加了异常组 ExceptionGroup 的概念,能够一次返回多个异常

1
2
3
4
5
6
7
8
9
10
11
def test():
raise ExceptionGroup(
"多个异常",
[
TypeError("type error"),
ValueError("value error"),
KeyError("key error")
]
)

test()

输出错误信息

1
2
3
4
5
6
7
8
9
10
11
12
13
+ Exception Group Traceback (most recent call last):
| File "/home/project/demo.py", line 11, in <module>
| test()
| File "/home/project/demo.py", line 2, in test
| raise ExceptionGroup(
| ExceptionGroup: 多个异常 (3 sub-exceptions)
+-+---------------- 1 ----------------
| TypeError: type error
+---------------- 2 ----------------
| ValueError: value error
+---------------- 3 ----------------
| KeyError: 'key error'
+------------------------------------

注意

  • ExceptionGroup 可以继续嵌套 ExceptionGroup
  • ExceptionGroup 需要使用 ExceptionGroup 来捕捉错误,也可以使用 except* 来捕捉
  • ExceptionGroup 继承自 Exception ,故可使用 Exception 来捕捉错误

except*

except* 用于一次匹配到多个异常,主要用于对 ExceptionGroup 进行错误捕捉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try
raise ExceptionGroup(
"多个异常",
[
TypeError("type error"),
ValueError("value error"),
KeyError("key error")
]
)
except* TypeError:
print('捕捉到TypeError')
except* ValueError:
print('捕捉到ValueError')
except* KeyError:
print('捕捉到KeyError')

输出

1
2
3
捕捉到TypeError
捕捉到ValueError
捕捉到KeyError

注意:

  • 如果没有完全捕捉 ExceptionGroup 中的所有错误,则还是会抛出错误
1
2
3
4
5
6
7
8
9
10
11
12
13
try
raise ExceptionGroup(
"多个异常",
[
TypeError("type error"),
ValueError("value error"),
KeyError("key error")
]
)
except* TypeError:
print('捕捉到TypeError')
except* ValueError:
print('捕捉到ValueError')

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
捕捉到TypeError
捕捉到ValueError
+ Exception Group Traceback (most recent call last):
| File "/home/project/demo.py", line 20, in <module>
| main()
| File "/home/project/demo.py", line 14, in main
| test()
| File "/home/project/demo.py", line 2, in test
| raise ExceptionGroup(
| ExceptionGroup: 多个异常 (1 sub-exception)
+-+---------------- 1 ----------------
| KeyError: 'key error'
+------------------------------------

增强异常的注释

在 Python3.11 中,内置了一个方式来向异常中增加备注信息

1
2
3
4
5
try:
import typer
except ModuleNotFoundError as e:
e.add_note("你还没有安装 typer")
raise

TOML解析器

在 Python3.11 中内置了一个 tomllib 模块进行toml解析,主要提供两个方法 loadloads

  • load 主要用来读取文件内容并解析,注意文件需要以二进制形式 rb 打开
  • loads 主要用来解析toml字符串内容

示例1:

新建一个 config.toml 文件,写入一下内容

1
2
[Params]
foo = 'bar'
1
2
3
4
5
import tomllib

with open('./config.toml', 'rb') as f:
config = tomllib.load(f)
print(config)

输出:

1
{'Params': {'foo': 'bar'}}

示例2:

1
2
3
4
5
6
7
8
import tomllib

toml_str = """
[Params]
foo = 'bar'
"""

print(tomllib.loads(toml_str))

输出

1
{'Params': {'foo': 'bar'}}

类型注解

Python3.11 主要新增了 TypeVarTupleTypeGuardSelfLiteralStringRequiredNotRequired 等类型

Self

新的 Self 注释提供了一种简单直观的方法来注释返回类实例的方法

1
2
3
4
5
6
7
8
9
10
11
class MyLock:
def __enter__(self) -> Self:
self.lock()
return self

...

class MyInt:
@classmethod
def fromhex(cls, s: str) -> Self:
return cls(int(s, 16))

Required 和 NotRequired

在使用 dataclass 装饰类的时候,可以指定参数是否必传

1
2
3
class Movie(TypedDict, total=False):
title: Required[str]
year: int