Python 中 typing 模块的类型注解
FreeGuideOnline
最新
2026-07-07
python def greet(name: str) -> str: return f"Hello, {name}"
`typing` 模块则提供了描述复杂数据结构的各种工具。
---
## 入门:基本类型注解
### 内置类型直接使用
对于简单类型,直接使用内置类型名即可,无需从 `typing` 导入:
```python
age: int = 25
price: float = 99.9
name: str = "Alice"
is_active: bool = True
对于函数参数与返回值:
def add(a: int, b: int) -> int:
return a + b
typing 模块常用复合类型
当数据结构变复杂,就需要引入 typing。
| 注解写法 | 含义 |
|---|---|
List[int] |
整数列表 |
Dict[str, float] |
字符串键,浮点数值的字典 |
Tuple[int, str] |
二元组,第一个 int 第二个 str |
Set[bytes] |
字节串集合 |
Optional[str] |
可以是 str 或 None |
Union[int, str] |
整数或字符串 |
Any |
任意类型,关闭类型检查 |
Callable[[int], str] |
可调用对象,接收 int 返回 str |
示例:
from typing import List, Dict, Tuple, Optional, Union, Any, Callable
def process_items(items: List[str]) -> None:
for item in items:
print(item)
def get_student_scores() -> Dict[str, float]:
return {"math": 92.5, "history": 88.0}
def get_dimensions() -> Tuple[int, int]:
return (1920, 1080)
def find_user(name: str) -> Optional[dict]:
# 可能返回字典,也可能返回 None
if name in database:
return database[name]
return None
def parse_value(val: Union[int, str]) -> float:
return float(val)
def execute(callback: Callable[[int], str], arg: int) -> str:
return callback(arg)
类型别名:给复杂类型起个名
一遍遍写 List[Dict[str, Union[int, str]]] 会让代码难以维护。用类型别名(Type Alias)提升可读性。
from typing import List, Dict, Union
# 定义别名
Row = Dict[str, Union[int, str]]
Table = List[Row]
def display_table(table: Table) -> None:
for row in table:
print(row)
从 Python 3.10 开始,还可以用 TypeAlias 显式标记(推荐):
from typing import TypeAlias
Row: TypeAlias = Dict[str, Union[int, str]]
结构更清晰的 TypedDict
当字典具有固定键和类型时,TypedDict 比普通 Dict 更严格、更友好。
from typing import TypedDict
class Movie(TypedDict):
title: str
year: int
rating: float
watched: bool
def record_movie(movie: Movie) -> None:
print(f"{movie['title']} ({movie['year']}) - {movie['rating']}")
# 正确的调用会被检查
movie_entry: Movie = {
"title": "Inception",
"year": 2010,
"rating": 8.8,
"watched": True
}
record_movie(movie_entry)
通过 TypedDict,IDE 可以提示字典应有字段,而 mypy 可以检测键名拼写错误。
泛型:打造可复用的容器类型
用 TypeVar 定义类型变量,可以创建泛型类或函数,保持类型安全的同时支持多种实际类型。
from typing import TypeVar, List
T = TypeVar('T')
def first_element(items: List[T]) -> T:
return items[0]
# 类型检查器能推断出:
# first_element([1,2,3]) 返回 int
# first_element(["a","b"]) 返回 str
自定义泛型类:
from typing import Generic, TypeVar
K = TypeVar('K')
V = TypeVar('V')
class Pair(Generic[K, V]):
def __init__(self, key: K, value: V):
self.key = key
self.value = value
p = Pair[str, int]("age", 30) # 类型为 Pair[str, int]
高级但实用的类型
Literal:字面量限定
限制变量或参数必须是某几个具体的值,非常适用于模式匹配或配置选项。
from typing import Literal
def set_mode(mode: Literal["auto", "manual", "eco"]) -> None:
print(f"Mode set to {mode}")
set_mode("auto") # 正确
set_mode("turbo") # mypy 会报错
Final:禁止覆盖的常量
from typing import Final
MAX_CONNECTIONS: Final = 100
# MAX_CONNECTIONS = 200 # mypy 会报错
也可以在类中声明 Final 方法、属性。
Protocol:结构化鸭子类型
定义接口但不需要显式继承,只要一个类具有指定的方法和属性,就被认为是该类型。
from typing import Protocol
class SupportsClose(Protocol):
def close(self) -> None: ...
class FileReader:
def close(self) -> None:
print("File closed")
def shutdown(resource: SupportsClose) -> None:
resource.close()
shutdown(FileReader()) # 通过类型检查
NoReturn:永不返回的函数
通常用于抛出异常或无限循环的函数。
from typing import NoReturn
def fatal_error(msg: str) -> NoReturn:
raise RuntimeError(msg)
常用类型兼容性场景
| 场景 | 正确写法 |
|---|---|
可以接收 None 的参数 |
Optional[str] 或 str | None (3.10+) |
| 参数可以是多种类型 | Union[int, str] 或 int | str |
| 不知道或不关心类型 | Any |
| 参数可以是多种类型但区分明确 | @overload 装饰器 |
| 字典缺少键但值可为 None | Dict[str, Optional[int]] |
| 表示“空” | 通常用 None,配合 Optional |
版本迁移:Python 3.9 / 3.10 后的新写法
自 Python 3.9 起,内置 list、dict 等已经支持泛型语法,不再必须从 typing 导入 List、Dict。
# Python 3.9+ 推荐
def get_names() -> list[str]:
return ["Alice", "Bob"]
def count_words(text: str) -> dict[str, int]:
words = text.split()
return {w: len(w) for w in words}
Python 3.10 引入了联合类型的 | 语法,完全取代 Union 和 Optional:
def process(data: int | str | None) -> list[int | str]:
if data is None:
return []
return [data]
不过在需要兼容旧版本时,仍应从 typing 导入 List 等。
如何开始使用类型检查
- 安装 mypy:
pip install mypy - 在项目根目录创建
mypy.ini或pyproject.toml配置基本选项。 - 运行:
mypy your_script.py