Python3.8下继承List的自定义类用泛型参数报错3.9正常如何解决
问题触发原因
Python 3.9 新增了PEP 585特性,支持直接对内置容器、typing模块的基础集合类型使用下标语法做类型标注,运行时会自动兼容非显式声明的泛型子类,所以你的代码在3.9环境可以正常运行。
而Python 3.8及更早版本中,类名[类型参数]的语法会触发typing模块的泛型校验逻辑,只有显式声明的泛型类才支持这种写法,你的Database类没有显式声明为泛型类,所以会抛出not a generic class的错误。
合理的兼容实现方式
你需要显式声明Database为泛型类,绑定对应的类型变量,这样既可以兼容Python 3.8+的所有版本,也能让mypy等类型校验工具正确推导元素类型:
from typing import TypedDict, List, TypeVar, Generic, Union # 声明泛型类型变量,约束Database内的元素类型 T = TypeVar('T') # 继承Generic[T]显式标记为泛型类,同时继承List[T]指定存储结构 class Database(Generic[T], List[T]): def __init__(self, *args): super().__init__(args) self.name = self.__class__.__name__ # 方法的入参和返回值都用泛型变量T标注 def add_entry(self, entry: T, **kwargs) -> T: for key, value in kwargs.items(): entry[key] = value self.append(entry) return entry def search(self, latest=True, **kwargs) -> Union[T, list[T]]: # 你的方法实现逻辑 pass class Attending(TypedDict): attending_username: str attending_email: str attending_phone: str # 这里的写法和你原来的一致,3.8及以上版本都可以正常运行 class Attendings(Database[Attending]): pass attendings = Attendings()
泛型类校验的作用
类名[参数]的语法本质是调用类的__class_getitem__魔法方法,typing模块的内置实现会先校验当前类是否为合法的泛型类,目的是避免开发者误用下标语法,确保类型标注的有效性,避免后续类型校验、运行时类型检查出现逻辑错误。
内容的提问来源于stack exchange,提问作者Aaron Earle-Richardson
相关产品推荐
相关产品推荐

