Python 3.11 新特性全面总结

发布时间:2022 年 10 月 24 日
官方文档:https://docs.python.org/zh-cn/3.11/whatsnew/3.11.html


一、性能大幅提升

Faster CPython 项目

Python 3.11 比 3.10 快 10-60%,标准基准测试平均提速 1.25x

主要优化方向:

  • 启动时间优化
  • 更快的函数调用
  • 更快的对象创建
  • 更高效的字典操作
  • 内联缓存优化

这是 Python 近年来最显著的性能提升,后续版本(3.12、3.13)将继续深化优化。


二、重磅新语法

1. 异常组与 except*(PEP 654)

支持同时抛出和处理多个无关异常,适合并发、批量操作场景:

# 抛出多个异常
exceptions = [
    ValueError("Invalid value"),
    TypeError("Wrong type"),
    RuntimeError("Failed")
]
raise ExceptionGroup("Multiple errors", exceptions)

# 使用 except* 处理异常组
try:
    ...
except* ValueError as eg:
    print(f"ValueError组: {eg.exceptions}")
except* TypeError as eg:
    print(f"TypeError组: {eg.exceptions}")

异常组特性:

  • ExceptionGroup / BaseExceptionGroup:异常组类型
  • except*:匹配异常组的子组
  • 支持嵌套异常组
  • eg.exceptions:访问组内所有异常

应用场景:

  • 并发任务中多个任务失败
  • 批量操作部分失败
  • 多重校验错误收集

2. 异常附加备注(PEP 678)

为异常添加上下文信息,不改变异常类型:

try:
    process_data(data)
except Exception as e:
    e.add_note(f"处理文件 {filename} 时失败")
    e.add_note(f"数据大小: {len(data)}")
    raise

# 输出示例
# Traceback (most recent call last):
#   ...
# ValueError: Invalid data
# 处理文件 data.json 时失败
# 数据大小: 1024

用途:

  • 添加调试信息
  • 记录上下文(文件名、行号、用户输入等)
  • 不需要自定义异常类

三、错误定位精确化(PEP 657)

Traceback 现在指向精确的表达式,而非整行:

# 之前(3.10)
Traceback (most recent call last):
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
AttributeError: 'NoneType' object has no attribute 'x'

# 现在(3.11)
Traceback (most recent call last):
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'

复杂表达式示例:

# 字典访问链
return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                        ~~~~~~~~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable

# 算术表达式
result = (x / y / z) * (a / b / c)
         ~~~~~~^~~
ZeroDivisionError: division by zero

禁用精确位置(减少内存占用):

python -X no_debug_ranges script.py
# 或
PYTHONNODEBUGRANGES=1 python script.py

四、新增标准库模块

1. tomllib — TOML 解析(PEP 680)

标准库终于内置 TOML 支持:

import tomllib

with open('config.toml', 'rb') as f:  # 注意:必须二进制模式
    config = tomllib.load(f)

# 或从字符串解析
config = tomllib.loads("""
[database]
host = "localhost"
port = 5432
""")

注意:tomllib 只支持读取,写入需使用第三方库如 tomli-w


五、标准库重要改进

1. asyncio.TaskGroup — 结构化并发

推荐的新并发模式,替代 create_task() + gather()

import asyncio

async def main():
    async with asyncio.TaskGroup() as tg:
        task1 = tg.create_task(fetch_data(url1))
        task2 = tg.create_task(fetch_data(url2))
        task3 = tg.create_task(fetch_data(url3))

    # TaskGroup 退出时自动等待所有任务完成
    print(task1.result(), task2.result(), task3.result())

优势:

  • 自动等待所有任务
  • 自动传播异常(使用 ExceptionGroup)
  • 更清晰的结构化并发

2. asyncio.timeout() — 超时上下文管理器

import asyncio

async def main():
    try:
        async with asyncio.timeout(10.0):
            await long_running_operation()
    except TimeoutError:
        print("操作超时")

3. asyncio.Barrier — 同步原语

import asyncio

async def worker(barrier, worker_id):
    print(f"Worker {worker_id} 准备就绪")
    await barrier.wait()
    print(f"Worker {worker_id} 开始执行")

async def main():
    barrier = asyncio.Barrier(3)
    async with asyncio.TaskGroup() as tg:
        for i in range(3):
            tg.create_task(worker(barrier, i))

4. datetime.UTC — 时区常量

from datetime import datetime, UTC

dt = datetime.now(UTC)  # 更简洁
# 等价于 datetime.now(timezone.utc)

5. datetime.fromisoformat() 增强

现在支持解析更多 ISO 8601 格式:

from datetime import datetime, date, time

datetime.fromisoformat('2024-01-15T10:30:45+08:00')
date.fromisoformat('2024-01-15')
time.fromisoformat('10:30:45+08:00')

6. math 模块新增函数

import math

math.exp2(3)    # 2^3 = 8.0
math.cbrt(27)   # 立方根 = 3.0

7. enum 模块大幅增强

from enum import Enum, StrEnum, Flag, auto

# StrEnum:成员必须是字符串
class Color(StrEnum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"

# Flag 增强:支持 len()、迭代、in
class Perm(Flag):
    R = auto()
    W = auto()
    X = auto()

p = Perm.R | Perm.W
len(p)           # 2
list(p)          # [Perm.R, Perm.W]
Perm.R in p      # True

8. hashlib.file_digest() — 文件哈希

import hashlib

with open('large_file.bin', 'rb') as f:
    digest = hashlib.file_digest(f, 'sha256')
print(digest.hexdigest())

9. functools.singledispatch 支持联合类型

from functools import singledispatch

@singledispatch
def process(arg):
    print(f"默认: {arg}")

@process.register
def _(arg: int | float):
    print(f"数值: {arg}")

@process.register
def _(arg: list | set):
    print(f"集合: {arg}")

10. re 支持原子分组和占有量词

import re

# 原子分组 (?>...)
re.match(r'(?>a+)b', 'aaab')  # 匹配失败时不会回溯

# 占有量词 *+、++、?+
re.match(r'a*+b', 'aaab')     # 占有式匹配

六、类型注解改进

1. 变长泛型(PEP 646)

支持 *Ts 语法,用于不定长类型参数:

from typing import TypeVarTuple

Ts = TypeVarTuple('Ts')

class Array:
    def __getitem__(self, index: tuple[*Ts]) -> Array[*Ts]: ...

2. Self 类型(PEP 673)

精确标注返回自身类型的方法:

from typing import Self

class Shape:
    def set_scale(self, scale: float) -> Self:
        self.scale = scale
        return self

class Circle(Shape):
    def set_radius(self, radius: float) -> Self:
        self.radius = radius
        return self

3. TypedDict 字段必需性标记(PEP 655)

from typing import TypedDict, Required, NotRequired

class Person(TypedDict):
    name: Required[str]      # 必需
    age: NotRequired[int]    # 可选
    email: str               # 根据 total 决定

4. 类型检查辅助函数

from typing import assert_never, reveal_type, assert_type, Never

# assert_never:确认代码不可达(类型检查器验证)
def handle(value: int | str):
    if isinstance(value, int):
        ...
    elif isinstance(value, str):
        ...
    else:
        assert_never(value)  # 类型检查器会报错如果有遗漏

# reveal_type:查看类型检查器推断的类型
reveal_type(x)  # 类型检查器会输出推断的类型

# assert_type:验证类型推断
assert_type(x, int)

# Never:永不返回的类型
def never_return() -> Never:
    raise RuntimeError()

5. typing.Any 支持子类化

from typing import Any

class DynamicObject(Any):
    """用于 mock 等高度动态的场景"""
    pass

七、其他语言改进

1. for 循环支持星号解包

for x, *rest in [(1, 2, 3), (4, 5, 6, 7)]:
    print(x, rest)
# 1 [2, 3]
# 4 [5, 6, 7]

2. 异步推导式嵌套

async def process():
    # 外层推导式自动变为异步
    results = [x async for x in gen() if await check(x)]

3. -P 选项与 PYTHONSAFEPATH

防止当前目录污染模块导入:

python -P script.py
# 或
PYTHONSAFEPATH=1 python script.py

这会禁止自动将脚本目录或当前目录添加到 sys.path,避免恶意模块覆盖。

4. 格式化字符串新增 z 选项

将负零转为正零:

f"{-0.0:.2f}"   # '-0.00'
f"{-0.0:.2fz}"  # '0.00'

5. 整数字符串转换限制

防止 DoS 攻击,默认限制 4300 位:

# 超过 4300 位会抛出 ValueError
int('1' * 5000)  # ValueError

# 可通过环境变量调整
# PYTHONINTMAXSTRDIGITS=0 python script.py  # 禁用限制

八、弃用与移除

重要弃用(PEP 594)

大量遗留标准库模块被弃用,将在 Python 3.13 移除:

弃用模块说明替代方案
cgicgitbCGI 支持使用 WSGI 框架
audioop音频操作使用第三方库
imghdr图像类型识别使用 puremagicfiletype
mailcapMIME 类型使用 mimetypes
msilibWindows 安装器使用第三方工具
telnetlibTelnet 协议使用 telnetlib3
xdrlibXDR 编码使用 construct

正式移除

移除内容说明
Py_UNICODE 编码器 APIPEP 624
bytessys.path3.6 起已失效

九、其他值得关注的变化

时间精度提升

  • Unixtime.sleep() 使用 clock_nanosleep(),精度 1 纳秒
  • Windows 8.1+time.sleep() 使用高精度定时器,精度 100 纳秒

线程锁使用单调时钟

threading.Lock.acquire() 使用 CLOCK_MONOTONIC,不受系统时间变化影响。

sqlite3 增强

  • 异常包含 SQLite 扩展错误码:sqlite_errorcodesqlite_errorname
  • 新增 serialize() / deserialize():数据库序列化与反序列化
  • 新增 blobopen():增量 I/O 操作
  • 新增 create_window_function():窗口函数

unittest 支持上下文管理器

import unittest

class MyTest(unittest.TestCase):
    def test_something(self):
        with self.enterContext(some_resource()) as r:
            # 资源自动清理
            ...

总结

Python 3.11 的核心亮点:

  1. 性能提升 10-60% — 近年来最显著的提速
  2. 异常组 ExceptionGroup + except* — 处理多个并发异常
  3. 精确错误定位 — Traceback 指向具体表达式
  4. 异常附加备注 — 丰富错误上下文
  5. tomllib — 标准库内置 TOML 解析
  6. asyncio.TaskGroup — 结构化并发新模式
  7. Self 类型 — 精确标注返回自身类型

Python 3.11 是一个性能与开发体验双提升的版本,错误定位改进让调试更轻松,异常组让并发错误处理更优雅,性能提升让 Python 在更多场景下保持竞争力。


参考:Python 3.11 官方文档 - What’s New
内容由 AI 整理生成,内容仅供参考,请仔细甄别。

更多推荐