文章
类型注解与泛型编程
demo
from typing import TypeVar, ClassVar, Generic
# 1. 定义类型变量 T,表示“未知的存储类型”
T = TypeVar("T")
# 2. 定义泛型类DataCache,继承Generic[T]
class DataCache(Generic[T]):
# 3. 适用ClassVar 声明类变量(所有示例共享的元数据)
max_capacity: ClassVar[int] = 100 # 类变量 默认最大容量
total_instances: ClassVar[int] = 0 # 类变量 统计创建实例数
def __init__(self, name: str, initial_data: T | None) -> None:
self.name = name # 实例变量
self._data: T | None = initial_data # 实例变量 类型是T
# 修改类变量(通过self或类名均可)
DataCache.total_instances += 1
print(f"当前实例总数:{DataCache.total_instances}")
def update(self, new_data: T) -> None:
"""更新数据, 参数类型必须和实例化是指定的T一致"""
self._data = new_data
def get(self) -> T | None:
"""获取数据,返回类型为T或None"""
return self._data
@classmethod
def get_max_capacity(cls) -> int:
"""类方法,访问类变量"""
return cls.max_capacity
if __name__ == '__main__':
# 实例化 指定T为int
cache_int: DataCache[int] = DataCache("整数缓存", 123)
cache_int.update(456)
value = cache_int.get()
print(f"整数缓存值:{value}")
# 实例化:指定T为str
cache_str: DataCache[str] = DataCache("字符串缓存", "Hello")
cache_str.update("World")
print(f"类变量 max_capacity: {DataCache.max_capacity}")
print(f"通过实例访问类变量:{cache_int.max_capacity}")
print(f"总实例数:{DataCache.total_instances}")
TypeVar(类型变量)- 作用:定义“一个占位符类型”。它用于创建泛型,表示“这个类型现在不确定,但一旦确定,后面所有用到它的地方都得是同一个类型”。
- 场景:比如写一个列表包装器,无论列表里存的是
int还是str,逻辑都一样,但你想保留具体类型信息给 IDE 和静态检查器(如 mypy)。
Generic(泛型基类)- 作用:让自定义的类支持泛型。继承
Generic[T]后,你的类就可以像list[int]一样,在实例化时指定具体的T是什么类型。 - 场景:封装数据结构(如仓库模式、结果集包装)时使用。
- 作用:让自定义的类支持泛型。继承
ClassVar(类变量注解)- 作用:专门用于注解类级别的变量(属于类本身,而不是实例)。如果不加这个,静态检查器会误以为这个变量是实例属性,可能导致误判。
- 场景:定义类的默认配置、计数器或常量池。
关键区别总结
| 模块 | 作用范围 | 核心目的 |
|---|---|---|
| TypeVar | 定义变量(占位符) | 声明“一个待定的类型” |
| Generic | 类继承 | 让类接受类型参数,成为泛型容器 |
| ClassVar | 变量注解(仅类属性) | 明确标注该变量属于类,而非实例 |