函数签名注解
def greet(name: str, age: int = 18) -> str:
return f"{name} 今年 {age}"
参数后加 : 类型,返回值用 -> 类型。Python 不会强制检查——它只是元数据,给 IDE / mypy / 同事看。
容器类型(Python 3.9+ 简写)
def process(nums: list[int]) -> dict[str, int]:
return {"count": len(nums)}
# Python 3.8 及以下要这样:
from typing import List, Dict
def process(nums: List[int]) -> Dict[str, int]: ...
新代码用小写内置——更简洁。
可选与联合:Optional / Union
def find(uid: int) -> str | None: # 3.10+ 写法
if uid in db:
return db[uid]
return None
# 等价的老写法
from typing import Optional
def find(uid: int) -> Optional[str]: ...
多种类型可能:
def to_int(x: int | str) -> int: # 3.10+
return int(x)
# 等价老写法
from typing import Union
def to_int(x: Union[int, str]) -> int: ...
Any:任意类型(逃避检查时用)
from typing import Any
def cache_get(key: str) -> Any:
return CACHE[key]
Any = "我不想标,类型检查器请放过"。慎用——失去类型注解的好处。
Literal:值的"枚举"
from typing import Literal
def open_mode(mode: Literal["r", "w", "a"]) -> None:
...
open_mode("r") # OK
open_mode("rw") # mypy 报错
Callable:函数类型
from typing import Callable
def apply(fn: Callable[[int, int], int], a: int, b: int) -> int:
return fn(a, b)
apply(lambda x, y: x + y, 3, 4)
Callable[[参数类型...], 返回类型]。
Generic / TypeVar:泛型
写一个保留类型信息的"通用容器":
from typing import TypeVar
T = TypeVar("T")
def first(xs: list[T]) -> T:
return xs[0]
x = first([1, 2, 3]) # x 推断成 int
s = first(["a", "b", "c"]) # s 推断成 str
类的泛型:
from typing import Generic
class Box(Generic[T]):
def __init__(self, value: T):
self.value = value
def get(self) -> T:
return self.value
b: Box[int] = Box(42)
v: int = b.get()
TypedDict:dict 的形状
from typing import TypedDict
class User(TypedDict):
name: str
age: int
def show(u: User) -> None:
print(u["name"])
show({"name": "WadeLy", "age": 30}) # OK
show({"name": "X"}) # mypy 报错:缺 age
标准复杂类型:怎么注解
from typing import Iterable, Iterator, Sequence, Mapping
def avg(nums: Iterable[float]) -> float: ... # 接收任意可迭代
def lines() -> Iterator[str]: ... # 返回迭代器
def head(seq: Sequence[int]) -> int: ... # 列表 / 元组都行
def show(d: Mapping[str, int]) -> None: ... # 只读字典
注解只是写给人看的——除非你跑 mypy
pip install mypy
mypy myfile.py
下一篇专门讲 mypy 怎么用。