Python 基础Technical Deep Dive

Python 类型提示:类型系统的艺术

发布时间2025/11/19
分类Python 基础
预计阅读8 分钟
作者吴长龙
*

类型提示让 Python 代码更健壮、更易维护。本文详细介绍基础类型、泛型、Protocol、TypeVar 等高级用法。

01.内容

# Python 类型提示:类型系统的艺术

类型提示(Type Hints)是 Python 3.5+ 引入的功能,让静态类型检查成为可能,大幅提升代码质量。

02.1. 基础类型提示

1.1 基本语法

python snippetpython
# 函数参数和返回值类型
def greet(name: str) -> str:
    return f"Hello, {name}!"

# 变量类型
age: int = 25
price: float = 19.99
is_active: bool = True

1.2 容器类型

python snippetpython
from typing import List, Dict, Set, Tuple

# 列表
names: List[str] = ["Alice", "Bob"]

# 字典
user: Dict[str, int] = {"age": 25, "score": 100}

# 集合
tags: Set[str] = {"python", "ai"}

# 元组(固定长度)
point: Tuple[int, int] = (10, 20)
person: Tuple[str, int, float] = ("Alice", 25, 1.65)

1.3 可选类型

python snippetpython
from typing import Optional

# Optional[X] 等价于 X | None
name: Optional[str] = None  # 可以是字符串或 None

# Python 3.10+ 可用
name: str | None = None

1.4 联合类型

python snippetpython
from typing import Union

# Union 可以是多种类型之一
result: Union[int, str] = 42  # int 或 str

# Python 3.10+ 可用
result: int | str = 42

03.2. 高级类型

2.1 泛型 (Generic)

python snippetpython
from typing import TypeVar, Generic

T = TypeVar('T')

class Container(Generic[T]):
    def __init__(self, value: T):
        self.value = value
    
    def get(self) -> T:
        return self.value

# 使用
int_container = Container[int](42)
str_container = Container[str]("hello")

2.2 泛型函数

python snippetpython
from typing import TypeVar

T = TypeVar('T')

def first(items: List[T]) -> T:
    """返回列表第一个元素"""
    return items[0]

# 类型自动推断
first([1, 2, 3])        # int
first(["a", "b", "c"])  # str
first([1, "a", 2.0])    # Union[int, str, float]

2.3 Protocol (结构子类型)

python snippetpython
from typing import Protocol

class Drawable(Protocol):
    def draw(self) -> None: ...

class Circle:
    def draw(self) -> None:
        print("画圆")

class Square:
    def draw(self) -> None:
        print("画正方形")

# 只要有 draw 方法就能传入
def render(shape: Drawable) -> None:
    shape.draw()

render(Circle())   # OK
render(Square())  # OK

2.4 TypeVar 约束

python snippetpython
from typing import TypeVar

# 约束类型范围
Number = TypeVar('Number', int, float)

def add(a: Number, b: Number) -> Number:
    return a + b

add(1, 2)      # OK (int)
add(1.0, 2.0)  # OK (float)
add(1, 2.0)    # Error! 类型不一致

04.3. Callable 类型

python snippetpython
from typing import Callable, Any

# 函数作为参数
def apply(func: Callable[[int], int], value: int) -> int:
    return func(value)

def double(x: int) -> int:
    return x * 2

apply(double, 5)  # 10

# 可变参数
def call_twice(func: Callable[..., Any], *args, **kwargs):
    func(*args, **kwargs)
    func(*args, **kwargs)

05.4. 字面量类型

python snippetpython
from typing import Literal

# 限制为特定值
def set_status(status: Literal["pending", "success", "error"]) -> None:
    print(f"状态: {status}")

set_status("pending")  # OK
set_status("unknown")  # Error!

# 结合 Union
def process(mode: Literal["read"] | Literal["write"]) -> None:
    pass

06.5. 类型别名

python snippetpython
from typing import List, Dict, Tuple

# 简单别名
UserId = int
Email = str

# 复杂类型别名
Response = Dict[str, str | int | bool]
Coordinate = Tuple[float, float]
Matrix = List[List[float]]

07.6. 运行时类型检查

6.1 isinstance 扩展

python snippetpython
from typing import get_type_hints, get_origin, get_args

def greet(name: str) -> str:
    return f"Hello, {name}!"

# 获取类型提示
hints = get_type_hints(greet)
# {'name': <class 'str'>, 'return': <class 'str'>}

# 检查泛型
List[str]           # get_origin() -> list
List[str]           # get_args() -> (str,)

6.3 pydantic 模型

python snippetpython
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int
    email: str | None = None

# 自动类型验证
user = User(name="Alice", age=25)
# 错误类型会自动转换或报错

08.7. mypy 静态检查

bash snippetbash
# 安装 mypy
pip install mypy

# 运行检查
mypy your_module.py

# 配置 pyproject.toml
# [tool.mypy]
# python_version = "3.11"
# warn_return_any = true
# warn_unused_configs = true

09.8. 总结

特性语法说明
基础类型x: int变量类型
返回值def f() -> int函数返回
ListList[int]列表类型
DictDict[str, int]字典类型
OptionalOptional[str]可选类型
UnionUnion[int, str]联合类型
GenericTypeVar('T')泛型
Protocolclass X(Protocol)结构类型

类型提示让 Python 代码更健壮,配合 mypy 可以实现静态类型检查。下一篇文章我们将介绍 pip 与虚拟环境,管理 Python 依赖。