Python typing 进阶
Python typing 进阶 的完整教学讲解。
Literal 字面量类型
基本写法:限定具体值
Literal[<值1>, <值2>]
# 限定参数只能取特定字面值
from typing import Literal
def set_mode(mode: Literal["r", "w", "a"]) -> None:
pass
set_mode("r")
TypedDict 结构化字典
基本写法:定义 TypedDict
class <名称>(TypedDict):\n <字段>: <类型>
# 类型化字典
from typing import TypedDict
class User(TypedDict):
id: int
name: str
active: bool
u: User = {"id": 1, "name": "Alice", "active": True}
基本写法:total=False 全可选
class <名称>(TypedDict, total=False):
# 所有字段可选
class Point(TypedDict, total=False):
x: int
y: int
基本写法:Required 与 NotRequired(3.11+)
Required[<类型>] | NotRequired[<类型>]
# 单字段控制可选性
from typing import TypedDict, Required, NotRequired
class Config(TypedDict):
host: Required[str]
port: NotRequired[int]
基本写法:ReadOnly 只读(3.13+)
ReadOnly[<类型>]
# 标记字段只读
from typing import TypedDict, ReadOnly
class Item(TypedDict):
id: ReadOnly[int]
name: str
Final 不可变注解
基本写法:声明 Final
<变量>: Final[<类型>] = <值>
# Final 表示变量不应被重新赋值
from typing import Final
MAX_SIZE: Final[int] = 100
基本写法:类属性 Final
<属性>: Final[<类型>]
# 类属性标记为 Final
class Config:
VERSION: Final[str] = "1.0.0"
Protocol 结构子类型
基本写法:定义 Protocol
class <名称>(Protocol):\n def <方法>(self): ...
# 鸭子类型的静态检查支持
from typing import Protocol
class Closeable(Protocol):
def close(self) -> None: ...
def close_all(items: list[Closeable]) -> None:
for item in items:
item.close()
基本写法:runtime_checkable
@runtime_checkable
# 允许 isinstance 检查
from typing import Protocol, runtime_checkable
@runtime_checkable
class Iterable2(Protocol):
def __iter__(self): ...
print(isinstance([1, 2], Iterable2))
TypeVar 类型变量
基本写法:定义 TypeVar
T = TypeVar("<名称>")
# 泛型类型变量
from typing import TypeVar
T = TypeVar("T")
def first(items: list[T]) -> T:
return items[0]
基本写法:带约束
TypeVar("<名称>", <类型1>, <类型2>)
# 限定类型取值范围
T = TypeVar("T", int, float)
def add(a: T, b: T) -> T:
return a + b
基本写法:bound 上界
TypeVar("<名称>", bound=<类型>)
# 上界约束
T = TypeVar("T", bound=str)
def upper(x: T) -> T:
return x.upper()
基本写法:TypeVar 默认值(3.13+)
TypeVar("<名称>", default=<类型>)
# 类型参数默认值
T = TypeVar("T", default=int)
def value(x: T = 0) -> T:
return x
ParamSpec 参数规格
基本写法:定义 ParamSpec
P = ParamSpec("<名称>")
# 捕获可调用对象的参数规格
from typing import ParamSpec, TypeVar, Callable
P = ParamSpec("P")
R = TypeVar("R")
def logged(func: Callable[P, R]) -> Callable[P, R]:
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
return func(*args, **kwargs)
return wrapper
TypeVarTuple 可变泛型
基本写法:定义 TypeVarTuple
Ts = TypeVarTuple("<名称>")
# 可变长度类型变量元组
from typing import TypeVarTuple, Unpack
Ts = TypeVarTuple("Ts")
def first(x: tuple[*Ts]) -> tuple[*Ts]:
return x
TypeAlias 类型别名
基本写法:类型别名
type <别名> = <类型>
# Python 3.12 新语法
type Vector = list[float]
def norm(v: Vector) -> float:
return sum(x * x for x in v) ** 0.5
基本写法:泛型别名
type <别名>[<参数>] = <类型>
# 带类型参数的别名
type Pair[T] = tuple[T, T]
def make(x: int) -> Pair[int]:
return (x, x)
TypeGuard 与 TypeIs 类型 narrowing
基本写法:TypeGuard
TypeGuard[<类型>]
# 自定义类型守卫
from typing import TypeGuard
def is_str_list(val: list) -> TypeGuard[list[str]]:
return all(isinstance(x, str) for x in val)
def process(val: list):
if is_str_list(val):
return [x.upper() for x in val]
基本写法:TypeIs(3.13+)
TypeIs[<类型>]
# TypeIs 提供更直观的双向 narrowing
from typing import TypeIs
def is_int(x: object) -> TypeIs[int]:
return isinstance(x, int)
overload 函数重载
基本写法:overload 装饰器
@overload
# 函数重载签名
from typing import overload
@overload
def parse(x: int) -> str: ...
@overload
def parse(x: str) -> int: ...
def parse(x):
if isinstance(x, int):
return str(x)
return int(x)
Generic 泛型类
基本写法:Generic 类
class <类>(Generic[T]):
# 泛型容器
from typing import Generic, TypeVar
T = TypeVar("T")
class Stack(Generic[T]):
def __init__(self):
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
基本写法:PEP 695 泛型语法(3.12+)
class <类>[T]:
# 新语法无需 TypeVar
class Stack[T]:
def __init__(self):
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
Never 与 NoReturn
基本写法:NoReturn
def <函数>() -> NoReturn:
# 表示函数永不返回
from typing import NoReturn
def fatal() -> NoReturn:
raise SystemExit(1)
基本写法:Never
def <函数>() -> Never:
# Never 表示永不产生值(3.11+)
from typing import Never
def unreachable() -> Never:
raise RuntimeError
override 装饰器(3.12+)
基本写法:标记覆盖
@typing.override
# 标记方法覆盖父类方法
from typing import override
class Base:
def run(self): pass
class Sub(Base):
@override
def run(self):
print("子类实现")