类型注解(Type Hint)

基本概念

类型注解是一种 静态类型提示机制,用于在代码中标注变量、函数参数、返回值等的预期类型
它不会改变 Python 的运行逻辑,只是为静态分析工具(如 mypy、pyright、pylance)提供类型信息

📘 举例:

1
2
def add(x: int, y: int) -> int:
return x + y

运行时效果完全一样,但编辑器 / 检查工具能检测类型错误:

1
add(1, "2")  # 类型检查器会提示错误

语法结构

用途 语法 示例
变量注解 变量名: 类型 count: int = 0
函数参数 def func(x: 类型): def greet(name: str):
返回值 -> 类型 def f() -> float:
类属性 在类体内注解 name: str
类型别名 类型名 = 类型 Vector = list[float]

常用类型注解

类型 示例 说明
基本类型 int, float, bool, str 基础数据类型
容器类型 list[int], dict[str, int], tuple[int, ...] 使用 [] 指定元素类型
可选类型 Optional[int]int | None 值可以为 None
联合类型 Union[int, str]int | str 多种可能类型
任意类型 Any 跳过类型检查
无返回值 -> None 表示函数无返回
可调用类型 Callable[[int, str], bool] 函数类型

📘 示例:

1
2
3
4
5
6
7
8
9
10
11
from typing import Optional, Union, Any, Callable

def process(value: Union[int, str, None]) -> Any:
if isinstance(value, int):
return value * 2
elif isinstance(value, str):
return value.upper()
return None

def apply(func: Callable[[int], int], x: int) -> int:
return func(x)

运行机制

类型注解只存在于运行时的函数对象中:

1
2
3
4
5
def greet(name: str) -> str:
return f"Hello {name}"

print(greet.__annotations__)
# {'name': <class 'str'>, 'return': <class 'str'>}

Python 本身 不会检查类型错误,但可以使用类型检查器:

1
mypy script.py

输出示例:

1
error: Argument 1 to "add" has incompatible type "str"; expected "int"

泛型(Generic)

泛型(Generic)是 可参数化的类型,即:让容器或类可以“带上类型信息”。

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
from typing import Generic, TypeVar, List

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()

使用:

1
2
3
4
5
6
7
s1 = Stack[int]()
s1.push(123)
print(s1.pop()) # int 类型

s2 = Stack[str]()
s2.push("abc")
print(s2.pop()) # str 类型

💡 编译期会检测类型一致性。

类型变量(TypeVar)

TypeVar 是定义泛型的核心工具。

1
2
3
from typing import TypeVar

T = TypeVar('T')

表示 “一个可变的类型参数”。

📘 用法举例:

1
2
3
4
T = TypeVar('T')

def first(items: list[T]) -> T:
return items[0]
  • 若传入 list[int] → 推断 T=int
  • 若传入 list[str] → 推断 T=str

✅ 类型安全:

1
2
first([1, 2, 3])   # 返回 int
first(["a", "b"]) # 返回 str

限制类型变量

使用 bound

让 T 必须是某个类型或其子类:

1
2
3
4
5
6
7
8
9
from typing import TypeVar

T = TypeVar('T', bound=str)

def shout(word: T) -> T:
return word.upper()

shout("hello") # ✅ 类型匹配
shout(123) # ❌ 类型不匹配

使用 constraints

限制为多个特定类型之一:

1
2
3
4
5
6
7
8
T = TypeVar('T', int, float)

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

double(3) # ✅ int
double(2.5) # ✅ float
double("a") # ❌ 类型错误

内建泛型类型

在 Python 3.9 之后,可以直接使用内建泛型而无需从 typing 导入:

旧写法(<=3.8) 新写法(>=3.9)
List[int] list[int]
Dict[str, int] dict[str, int]
Tuple[int, ...] tuple[int, ...]
Optional[int] int | None
Union[int, str] int | str

高级泛型应用

协变与逆变

TypeVar 可以指定是否协变或逆变(通常用于类型安全的泛型容器):

1
2
3
from typing import TypeVar

T_co = TypeVar('T_co', covariant=True)
  • 协变(covariant):子类可代替父类(如 List[Dog]List[Animal] 的子类型)
  • 逆变(contravariant):父类可代替子类(常用于函数参数)

这种机制在复杂类型系统中确保“类型替换安全”。

泛型函数与类型推导

1
2
3
4
5
6
from typing import TypeVar

T = TypeVar('T')

def identity(x: T) -> T:
return x
  • identity(10)T=int
  • identity("hi")T=str

类型检查器自动推导,不需要显式指定。

多类型变量函数

1
2
3
4
5
6
7
from typing import TypeVar

T = TypeVar('T')
U = TypeVar('U')

def pair(a: T, b: U) -> tuple[T, U]:
return (a, b)

✅ 结果类型自动推导为 tuple[int, str] 等。

高级类型工具

类型工具 含义 示例
Any 任意类型(跳过检查) x: Any
NoReturn 永不返回(函数异常结束) def fail() -> NoReturn:
Literal 限定具体值 Literal["GET", "POST"]
Annotated 额外元数据 Annotated[int, "age"]
Final 不可重写 PI: Final = 3.14
ClassVar 类变量(非实例变量) counter: ClassVar[int]
Self 类自身类型(Python 3.11+) def copy(self) -> Self:

类型检查与验证

静态检查

  • mypy
  • pyright
  • pylance(VS Code 内置)

运行:

1
mypy myscript.py

动态验证

可以结合 typing + pydanticbeartypetypeguard在运行时验证类型

1
2
3
4
5
6
7
from typeguard import typechecked

@typechecked
def add(x: int, y: int) -> int:
return x + y

add(1, "2") # ❌ TypeError at runtime

实际应用

数据处理函数

1
2
def average(values: list[float]) -> float:
return sum(values) / len(values)

泛型容器

1
2
3
4
5
6
7
8
9
from typing import Generic, TypeVar

T = TypeVar('T')

class Box(Generic[T]):
def __init__(self, content: T):
self.content = content

b = Box[str]("apple")

自定义协议

1
2
3
4
5
6
7
from typing import Protocol

class Speakable(Protocol):
def speak(self) -> str: ...

def make_speak(x: Speakable):
print(x.speak())

总结表

概念 含义 示例
类型注解 给变量/函数加类型提示 x: int, def f(x: str) -> bool:
类型变量 泛型类型参数 T = TypeVar('T')
泛型类 类中使用类型变量 class Box(Generic[T]): ...
联合类型 多种可能类型 int | str
可选类型 允许 None Optional[int]
约束类型 限定范围 TypeVar('T', int, float)
绑定类型 必须是某类型子类 TypeVar('T', bound=BaseClass)
类型检查器 静态分析工具 mypy, pyright