在 Python 中,泛型(Generics) 的概念主要用于 类型注解(type hints) ,帮助开发者在静态类型检查时(例如使用 mypy
、pyright
)获得更精确的类型推断。
泛型不影响程序的运行行为 ,而是让代码在 语义上更清晰、更安全。
🧠 一、泛型是什么?
泛型的核心思想:
"一个类型对多种数据类型通用"。
例如,List[int]
表示一个只能装 int 的列表,
List[str]
表示一个只能装 str 的列表。
这可以防止混用类型的错误:
python
from typing import List
def sum_list(numbers: List[int]) -> int:
return sum(numbers)
print(sum_list([1, 2, 3])) # ✅ 正常
print(sum_list(["a", "b"])) # ❌ 类型检查器会报错
🧩 二、使用泛型类型(TypeVar)
TypeVar
用于声明一个泛型参数:
python
from typing import TypeVar, List
T = TypeVar("T") # 声明一个泛型类型变量
def first_element(elements: List[T]) -> T | None:
if elements:
return elements[0]
return None
🔹 用法说明:
T
表示一个"占位类型";- 函数返回的类型与输入
List[T]
的元素类型一致; - 当传入
List[int]
时,返回值类型自动推断为int
。
python
print(first_element([1, 2, 3])) # 返回 int
print(first_element(["a", "b"])) # 返回 str
🧱 三、在类中使用泛型
泛型类可以让类在定义时不固定数据类型:
python
from typing import Generic, TypeVar
T = TypeVar("T")
class Box(Generic[T]):
def __init__(self, value: T):
self.value = value
def get(self) -> T:
return self.value
✅ 使用时指定类型:
python
box1 = Box
box2 = Box[str]("hello")
print(box1.get()) # int
print(box2.get()) # str
⚙️ 四、带约束的泛型
可以通过 bound
或者 constraints
限制泛型类型:
1️⃣ bound(上界约束)
python
from typing import TypeVar
class Animal:
def speak(self):
print("Animal sound")
class Dog(Animal):
def speak(self):
print("Woof!")
T = TypeVar("T", bound=Animal)
def make_speak(animal: T) -> None:
animal.speak()
make_speak(Dog()) # ✅ OK
make_speak(Animal()) # ✅ OK
# make_speak("string") ❌ 报类型错误
2️⃣ constraints(多类型约束)
python
from typing import TypeVar
T = TypeVar("T", int, float) # 只能是 int 或 float
def double(x: T) -> T:
return x * 2
print(double(10)) # ✅ int
print(double(3.14)) # ✅ float
# print(double("a")) ❌ 类型检查失败
🧩 五、常用泛型容器
Python 的标准库 typing
模块已经提供了许多泛型容器:
泛型类型 | 说明 |
---|---|
List[T] |
列表 |
Dict[K, V] |
字典 |
Tuple[T, ...] |
元组 |
Set[T] |
集合 |
Iterable[T] |
可迭代对象 |
Optional[T] |
T 或 None |
Union[A, B] |
A 或 B |
例如:
python
from typing import Dict, List, Optional, Union
def process_data(data: Dict[str, List[int]]) -> Optional[Union[int, float]]:
if "scores" in data:
return sum(data["scores"]) / len(data["scores"])
return None
🧭 六、Python 3.9+ 简写语法
在 Python 3.9 之后,可以用更简洁的语法:
python
# 旧写法
from typing import List, Dict
def f1(data: List[int]) -> Dict[str, int]:
...
# 新写法(推荐)
def f2(data: list[int]) -> dict[str, int]:
...
✅ 小结
概念 | 用法示例 |
---|---|
定义泛型变量 | T = TypeVar("T") |
泛型函数 | def func(x: T) -> T: |
泛型类 | class Box(Generic[T]): |
约束类型 | TypeVar("T", bound=Base) 或 TypeVar("T", int, float) |
内置泛型容器 | list[T], dict[K, V], tuple[T, ...] |