Python学习(11) ----- Python的泛型

在 Python 中,泛型(Generics) 的概念主要用于 类型注解(type hints) ,帮助开发者在静态类型检查时(例如使用 mypypyright)获得更精确的类型推断。

泛型不影响程序的运行行为 ,而是让代码在 语义上更清晰、更安全


🧠 一、泛型是什么?

泛型的核心思想:

"一个类型对多种数据类型通用"。

例如,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] TNone
Union[A, B] AB

例如:

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, ...]

相关推荐
没有梦想的咸鱼185-1037-16635 小时前
AI Agent结合机器学习与深度学习在全球气候变化驱动因素预测中的应用
人工智能·python·深度学习·机器学习·chatgpt·数据分析
讽刺人生Yan5 小时前
RFSOC学习记录(五)带通采样定理
学习·fpga·rfsoc
加号35 小时前
【C#】获取电脑网卡MAC地址
windows·c#
报错小能手6 小时前
linux学习笔记(49)Redis详解(1)
linux·笔记·学习
QT 小鲜肉6 小时前
【个人成长笔记】在本地Windows系统中如何正确使用adb pull命令,把Linux系统中的文件或文件夹复制到本地中(亲测有效)
linux·windows·笔记·学习·adb
测试19986 小时前
Selenium自动化测试+OCR-获取图片页面小说详解
自动化测试·软件测试·python·selenium·测试工具·ocr·测试用例
闲人编程6 小时前
使用MLflow跟踪和管理你的机器学习实验
开发语言·人工智能·python·机器学习·ml·codecapsule
panplan.top6 小时前
Tornado + Motor 微服务架构(Docker + 测试 + Kubernetes)
linux·python·docker·微服务·k8s·tornado
看兵马俑的程序员6 小时前
RAG实现-本地PDF内容加载和切片
开发语言·python·pdf