第 30 章 Python 新特性速览(3.9 — 3.13)
30.1 Python 3.9
字典合并运算符
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
# | 创建新字典(右侧优先)
merged = d1 | d2 # {'a': 1, 'b': 3, 'c': 4}
# |= 就地更新
d1 |= d2 # d1 变为 {'a': 1, 'b': 3, 'c': 4}
内置类型用于类型提示
# 3.9 之前
from typing import List, Dict, Tuple, Set
def process(items: List[str]) -> Dict[str, int]:
pass
# 3.9+ 直接用内置类型
def process(items: list[str]) -> dict[str, int]:
pass
# tuple, set, frozenset, type 同样支持
coords: tuple[float, float] = (3.0, 4.0)
unique: set[int] = {1, 2, 3}
字符串方法增强
# removeprefix / removesuffix
"HelloWorld".removeprefix("Hello") # "World"
"HelloWorld".removesuffix("World") # "Hello"
"HelloWorld".removeprefix("xyz") # "HelloWorld"(无匹配不变)
# 之前的做法(容易出错)
s = "test_file.py"
# s[:-3] # 如果不是 .py 结尾会出错
s.removesuffix(".py") # 安全
zoneinfo 模块
from datetime import datetime
from zoneinfo import ZoneInfo
dt = datetime(2026, 3, 31, 12, 0, tzinfo=ZoneInfo("Asia/Shanghai"))
print(dt) # 2026-03-31 12:00:00+08:00
# 时区转换
tokyo_time = dt.astimezone(ZoneInfo("Asia/Tokyo"))
print(tokyo_time) # 2026-03-31 13:00:00+09:00
30.2 Python 3.10
match-case 结构化模式匹配
# 值匹配
match command:
case "quit" | "exit":
sys.exit()
case "help":
show_help()
case _:
print("未知命令")
# 结构匹配
match point:
case (0, 0):
print("原点")
case (x, 0):
print(f"x 轴: {x}")
case (0, y):
print(f"y 轴: {y}")
case (x, y) if x == y:
print(f"对角线: ({x}, {y})")
case (x, y):
print(f"普通点: ({x}, {y})")
# 类模式
match event:
case Click(x=x, y=y):
handle_click(x, y)
case KeyPress(key="q"):
quit()
# 映射模式
match config:
case {"database": {"host": host, "port": port}}:
connect(host, port)
更好的错误信息
# 3.10 之前的错误信息
# SyntaxError: invalid syntax
# 3.10+ 精确指出问题位置
expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4, 38: 4, 39: 4}
# SyntaxError: '{' was never closed
# 括号不匹配
# x = (1 + 2
# SyntaxError: '(' was never closed
# 属性拼写建议
# import collections
# collections.namedtple
# AttributeError: module 'collections' has no attribute 'namedtple'. Did you mean: 'namedtuple'?
带括号的上下文管理器
# 3.10+ 可以用括号包裹多行
with (
open("input.txt") as fin,
open("output.txt", "w") as fout,
):
fout.write(fin.read())
TypeAlias 和 ParamSpec
from typing import TypeAlias, ParamSpec, Callable
# 明确声明类型别名
Vector: TypeAlias = list[float]
# 装饰器的精确类型
P = ParamSpec("P")
def decorator(func: Callable[P, int]) -> Callable[P, str]:
...
30.3 Python 3.11
异常组与 except*
# ExceptionGroup — 同时抛出多个异常
eg = ExceptionGroup("多个错误", [
ValueError("值错误"),
TypeError("类型错误"),
])
try:
raise eg
except* ValueError as e:
print(f"处理 ValueError: {e.exceptions}")
except* TypeError as e:
print(f"处理 TypeError: {e.exceptions}")
异常注解
# 给异常添加注释
try:
1 / 0
except ZeroDivisionError as e:
e.add_note("这发生在处理用户输入时")
e.add_note(f"用户ID: 12345")
raise
# ZeroDivisionError: division by zero
# 这发生在处理用户输入时
# 用户ID: 12345
tomllib — TOML 解析
import tomllib
with open("config.toml", "rb") as f:
config = tomllib.load(f)
# 或从字符串解析
data = tomllib.loads("""
[database]
host = "localhost"
port = 5432
""")
print(data["database"]["host"]) # localhost
速度提升
Python 3.11 比 3.10 平均快 10-60%(Faster CPython 项目):
- 自适应特化解释器
- 内联 Python 函数调用
- 零开销的异常处理(没有异常时)
TaskGroup
import asyncio
async def main():
async with asyncio.TaskGroup() as tg:
task1 = tg.create_task(coro1())
task2 = tg.create_task(coro2())
# 所有任务完成后才继续
print(task1.result(), task2.result())
30.4 Python 3.12
type 语句 — 类型别名新语法
# 旧方式
from typing import TypeAlias
Vector: TypeAlias = list[float]
# 新方式(3.12+)
type Vector = list[float]
type Matrix = list[Vector]
# 泛型类型别名
type ListOrSet[T] = list[T] | set[T]
泛型函数和类的新语法
# 旧方式
from typing import TypeVar, Generic
T = TypeVar("T")
def first(items: list[T]) -> T:
return items[0]
class Stack(Generic[T]):
...
# 新方式(3.12+)
def first[T](items: list[T]) -> T:
return items[0]
class Stack[T]:
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
f-string 改进
# 3.12+ f-string 内部可以使用任意表达式,包括:
# 嵌套引号(同种引号也可以)
name = "world"
print(f"Hello {"world"}") # Hello world
# 多行表达式
print(f"result = {
1 + 2
+ 3
}") # result = 6
# 嵌套 f-string
print(f"{'hello' + f' {name}'}") # hello world
# 反斜杠和注释
songs = ["Take me back", "Move"]
print(f"songs = {"\n".join(songs)}")
改进的错误消息
# 更有用的 NameError 建议
# import sys
# sys.evxit()
# AttributeError: module 'sys' has no attribute 'evxit'. Did you mean: 'exit'?
# 导入建议
# from datetime import datatime
# ImportError: cannot import name 'datatime' from 'datetime'.
# Did you mean: 'datetime'?
每个子解释器独立的 GIL
Python 3.12 为子解释器实现了独立的 GIL(PEP 684),为未来的真正并行奠定基础。
30.5 Python 3.13
free-threaded 模式(实验性)
Python 3.13 引入了实验性的无 GIL 构建:
# 安装 free-threaded 版本
# 需要特殊构建或使用支持的安装器
# 检查是否启用
python -c "import sys; print(sys._is_gil_enabled())"
# False(如果是 free-threaded 构建)
import threading
import sys
# 在 free-threaded Python 中,CPU 密集型多线程可以真正并行
def cpu_work(n):
total = 0
for i in range(n):
total += i * i
return total
# 这些线程现在可以在不同 CPU 核心上并行执行
threads = [threading.Thread(target=cpu_work, args=(10_000_000,)) for _ in range(4)]
for t in threads: t.start()
for t in threads: t.join()
改进的交互式解释器
Python 3.13 的 REPL 基于 PyREPL,支持:
# 多行编辑(方向键导航)
# 语法高亮
# 粘贴模式(自动检测多行粘贴)
# 更好的历史记录
# 颜色化输出
# 按 F1 查看帮助
# 支持粘贴完整代码块
改进的错误消息(继续完善)
# 更精确的错误指示
# name = "Alice
# SyntaxError: unterminated string literal (detected at line 1)
# 更好的类型错误提示
# "hello" + 42
# TypeError: can only concatenate str (not "int") to str.
# Did you mean: "hello" + str(42)?
弃用和移除
# 许多旧模块在 3.13 中被移除
# aifc, audioop, chunk, cgi, cgitb, imghdr, mailcap,
# msilib, nis, nntplib, ossaudiodev, pipes, sndhdr,
# spwd, sunau, telnetlib, uu, xdrlib
本章小结:Python 持续进化。3.9-3.13 的重要特性包括:字典合并运算符、match-case 模式匹配、异常组、type 语句、泛型新语法、f-string 增强。最重要的发展方向是 free-threaded Python——移除 GIL 的实验已经开始,这将从根本上改变 Python 的并发能力。保持对新版本的关注,及时采用新特性让代码更现代、更高效。