Skip to content

What’s New In Python 3.13

Important

  1. 一个新的交互式解释器
  2. 在终端显示异常信息时默认支持色彩显示
  3. 一个支持禁用 GIL 的自由线程版本的解释器
  4. 使用未经自由线程版本构建的 C-API 扩展会导致GIL 被启用
  5. from __future__ import * 不再有效

replace protocol

通过copy.replace 简化创建副本的修改, 支持部分不可变对象, 包括namedtuple

需要对象支持__replace__方法

Example
from copy import replace
from collections import namedtuple

# 定义一个简单的命名元组
Person = namedtuple('Person', ['name', 'age'])

p1 = Person(name='Alice', age=30)
print('原对象:', p1)

# 使用 copy.replace 创建一个修改了 age 字段的新对象
p2 = replace(p1, age=31)
print('修改后的对象:', p2)

Nice

  1. 对于和标准库同名的脚本名称有更友好的错误提示
  2. asyncio.as_completed() 支持异步迭代
  3. 在未活动的asyncio.TaskGroup上通过create_task创建任务时, 会立即关闭该协程
  4. itertools.batched 可以通过strict 要求参数长度必需是 size 的倍数

ConfigParser.UNNAMED_SECTION

支持通过UNNAMED_SECTION 访问顶层无Section的字段

Example
import configparser

config_text = '''
option = value

[Section 2]
another = val
'''

config = configparser.ConfigParser(allow_unnamed_section=True)
config.read_string(config_text)

print(config.get(configparser.UNNAMED_SECTION, 'option'))  
# 'value'
print(config.get('Section 2', 'another')) 
# 'val'

glob.translate

shell 风格的通配符转换为对应的正则表达式

Example
import glob
import re

pattern = '**/*.txt'
regex_pattern = glob.translate(pattern, recursive=True)
print(regex_pattern)

re_obj = re.compile(regex_pattern)
print(re_obj.match('foo/bar/baz.txt'))

Type Annotation

ReadOnly

PEP 705: Add ReadOnly, a special typing construct to mark a TypedDict item as read-only for type checkers

Example
from typing import TypedDict, ReadOnly

class Leader(TypedDict):
    name: ReadOnly[str]
    age: int

author: Leader = {'name': 'Yang Zhou', 'age': 30}
author['age'] = 31       # 类型检查通过
author['name'] = 'Yang'  # 类型检查报错,因为 name 是只读

TypeIs

PEP 742: Add TypeIs, a typing construct that can be used to instruct a type checker how to narrow a type.

TypeGuard 对于 if 不成立的剩余部分,会缩窄当前类型范围, 而 TypeIs 则不会

Example
from typing import TypeGuard, TypeIs

def is_str_typeguard(x: str|float) -> TypeGuard[str]:
    return isinstance(x, str)

def is_str_typeis(x: str|float) -> TypeIs[str]:
    return isinstance(x, str)

def demo1(val: str|float):
    if is_str_typeis(val):
        # val 是 str
        ...
    else:
        # val 是 float,TypeIs 收窄为剩余类型
        ...

def demo2(val: str|float):
    if is_str_typeguard(val):
        # val 是 str
        ...
    else:
        # val 仍是 str|object
        ...

NoDefault

typing.NoDefault用于区分 None, 表示该类型没有默认参数, 而不是默认为 None

Trivial

  1. 一个支持 JIT 的实验性构建参数
  2. PEP738: 添加 Android 作为支持平台
  3. PEP730: 添加 iOS 作为支持平台
  4. 编译器会在文档字符串移除常见的前导空白字符
  5. 通过 PYTHON_HISTORY 变量指定.python_history文件的路径
  6. __firstlineno__ 执行类定义的首行代码行号
  7. exec()eval()接受 globalslocals作为参数
  8. property装饰的方法添加__name__属性
  9. StreamReader.readuntil()接受分隔符元组作为参数, 遇到其一停止
  10. 修复asyncio.TaskGroup因嵌套取消而导致的冲突.
  11. os.process_cpu_count() 代替 os.cpu_count() 作为concurrent.futures默认的工作线程和进程数量选择
  12. doctest默认输出为彩色
  13. enum.EnumDict 可以被直接使用了
  14. ipaddress.IPv4Address 通过 ipv6_mapped 将 v4 地址用 v6 的格式表示

Annotation Lambda

类内部的类型注解支持在类内的 lambda 表达式中使用

Example
class C[T]:
    type Alias = lambda: T

global in except

如果在 else 中使用到全局变量, 则允许在 except 语句中声明该全局变量

Example
x = 0
try:
    1 / 0
except ZeroDivisionError:
    global x
    x = 10  
else:
    print(f'No error, x is {x}')

static_attributes

支持通过__static_attributes__访问通过self.<name>赋值的属性元组

Example
class MyClass:
    def __init__(self):
        self.a = 1
        self.b = 2
    def set_c(self):
        self.c = 3
print(MyClass.__static_attributes__)
# ('a', 'b', 'c')

总结

  1. 一个支持禁用 GIL 的自由线程版本的解释器, 如 3.13.73.13.7t, 带 t 的解释器版本为移除 GIL 的自由线程版本
  2. from __future__ import * 不再有效
  3. TypedDict增加ReadOnly注解
  4. 更加友好的交互式解释器
  5. 异常显示支持色彩