1. typing 模块 #

1.1 导入方式 #

# Python 3.9+:一般只需导入高级类型
from typing import Optional, Callable

# 需要兼容旧版本或用到泛型时
from typing import TypeVar, Generic

2. 基本类型提示 #

2.1 函数注解 #

# 定义问候函数,参数和返回值均为 str
def greet(name: str) -> str:
    # 返回格式化问候语
    return f"Hello, {name}"

# 定义计算圆面积的函数
def calculate_area(radius: float) -> float:
    # 用近似 π 计算面积
    return 3.14159 * radius ** 2

# 定义判断偶数的函数
def is_even(number: int) -> bool:
    # 余数为 0 即为偶数
    return number % 2 == 0

2.2 变量注解 #

# 声明字符串变量
name: str = "Alice"
# 声明整型变量
count: int = 0
# 声明字符串列表
items: list[str] = ["a", "b", "c"]

3. 容器类型 #

# 接收整数列表,返回浮点数列表
def process_numbers(numbers: list[int]) -> list[float]:
    # 每个元素乘以 1.5
    return [x * 1.5 for x in numbers]

# 返回姓名到成绩的映射
def get_student_grades() -> dict[str, int]:
    return {"Alice": 95, "Bob": 87}

# 返回二维坐标元组
def get_coordinates() -> tuple[float, float]:
    return (40.7128, -74.0060)

# 字符串列表去重为集合
def get_unique_items(items: list[str]) -> set[str]:
    return set(items)

4. 高级类型提示 #

4.1 Optional(可能为 None) #

# 按 ID 查找用户,找不到返回 None
def find_user(user_id: int) -> str | None:
    # 模拟用户数据字典
    users = {1: "Alice", 2: "Bob"}
    # get 在键不存在时返回 None
    return users.get(user_id)

# 调用查找函数
user = find_user(1)
# 判空后再使用,避免 None 错误
if user is not None:
    print(f"Found: {user}")

Optional[str] 等价于 str | None(Python 3.10+ 推荐后者)。

4.2 Union(多种类型之一) #

# 接受 int、float 或 str,统一转为字符串
def process_value(value: int | float | str) -> str:
    return str(value)

# 传入整数,合法
process_value(42)
# 传入字符串,同样合法
process_value("hello")

4.3 Callable(函数类型) #

# 导入 Callable 类型
from typing import Callable

# 对列表每个元素应用传入的一元函数
def apply_operation(
    numbers: list[int],
    operation: Callable[[int], int]
) -> list[int]:
    return [operation(x) for x in numbers]

# 用 lambda 对每个数求平方
apply_operation([1, 2, 3], lambda x: x ** 2)

4.4 Literal(固定字面值) #

限制参数只能是几个固定字符串,常用于状态、模式等配置:

# 导入 Literal 类型
from typing import Literal

# 限制 status 只能是三个固定字符串之一
def set_status(status: Literal["active", "inactive", "pending"]) -> None:
    print(f"Status: {status}")

# 传入合法字面值
set_status("active")
# 传入非法值时,静态检查会警告
# set_status("invalid")

5. 泛型简介 #

5.1 类型变量 #

# 导入 TypeVar
from typing import TypeVar

# 声明泛型类型变量 T
# 左边的 T:是一个 Python 变量名,用于在代码中引用这个类型变量。
# 右边的 'T'(字符串):是类型变量的 内部名称,主要用于 调试输出、错误消息、类型签名 的显示。
T = TypeVar('T')

# 返回列表首元素,类型与元素一致
def first_element(items: list[T]) -> T:
    return items[0]

# T 被推断为 int
first_element([1, 2, 3])
# T 被推断为 str
first_element(["a", "b"])

5.2 泛型类 #

下例演示了如何自定义一个支持任意元素类型的泛型栈:

# 导入泛型基类和类型变量
from typing import Generic, TypeVar

# 声明类型变量 T
T = TypeVar('T')

# 定义泛型栈,T 表示元素类型
class Stack(Generic[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()

6. 实际应用示例 #

# 按条件筛选用户,返回结果和数量
def filter_users(
    users: list[dict[str, str]],
    filters: dict[str, str] = {}
) -> tuple[list[dict[str, str]], int]:
    """按条件筛选用户,返回筛选结果和数量。"""
    # 保留满足所有筛选条件的用户
    result = [
        user for user in users
        if all(user.get(k) == v for k, v in filters.items())
    ]
    # 返回结果列表和匹配数量
    return result, len(result)

# 构造测试用户数据
users = [
    {"name": "Alice", "role": "admin"},
    {"name": "Bob", "role": "user"},
    {"name": "Charlie", "role": "admin"},
]
# 筛选 role 为 admin 的用户
filtered, count = filter_users(users, {"role": "admin"})
print(f"找到 {count} 个管理员: {filtered}")

7. 总结 #

7.1 常用写法速查 #

# 基础函数注解(函数体省略)
from typing import Callable


def fn(name: str, age: int) -> bool: ...

# 空字符串列表
items: list[str] = []
# 空字符串到整数的字典
mapping: dict[str, int] = {}
# 二维浮点坐标
point: tuple[float, float] = (0.0, 0.0)

# 可能返回 None 的查找函数
def find(id: int) -> str | None: ...

# 接受 int 或 str 的解析函数
def parse(value: int | str) -> str: ...

# 接受字符串回调的函数
def run(callback: Callable[[str], None]) -> None: ...

7.2 最佳实践 #