如何为泛型类的方法指定对应泛型参数的泛型返回类型?
解决GameObjects.to_dict的泛型类型匹配问题
问题场景
GameObjects.to_dict方法需要根据内部存储的GameObject子类类型,返回对应的TypedDict泛型列表,但当前代码运行mypy时会报错:
line 37: error: List comprehension has incompatible type List[GameObjectDict]; expected List[D] [misc]
同时希望避免为每个类似Assets的容器单独创建具体类,保持代码复用性。
问题根源
原代码中GameObjects仅泛型了T(GameObject类型),但未将T与对应的D(TypedDict类型)关联起来,导致mypy无法推断item.to_dict()的返回类型就是预期的D。
解决方案
调整类型变量的约束关系,让GameObjects同时泛型T和D,并确保T类型的对象必然能返回D类型的字典。修改后的完整代码如下:
from abc import ABC, abstractmethod from dataclasses import dataclass, field from pathlib import Path from typing import Generic, TypedDict, TypeVar # 调整类型变量约束:T必须是返回D类型字典的AbstractGameObject子类 D = TypeVar("D", bound="GameObjectDict") T = TypeVar("T", bound="AbstractGameObject[D]") class GameObjectDict(TypedDict): name: str class AssetDict(GameObjectDict): path: str class AbstractGameObject(ABC, Generic[D]): @abstractmethod def to_dict(self) -> D: raise NotImplementedError @dataclass class GameObject(AbstractGameObject[GameObjectDict]): name: str def to_dict(self) -> GameObjectDict: return GameObjectDict(name=self.name) @dataclass class GameObjects(Generic[T, D]): items: dict[str, T] = field(default_factory=dict) def to_dict(self) -> list[D]: return [item.to_dict() for item in self.items.values()] def add(self, item: T): if item.name in self.items.keys(): raise KeyError(f"{item.name} already exists") self.items[item.name] = item @dataclass class Asset(GameObject): path: Path def to_dict(self) -> AssetDict: return AssetDict(**super().to_dict(), path=str(self.path)) # 实例化时指定对应的GameObject类型和TypedDict类型,无需创建单独的Assets类 Assets = GameObjects[Asset, AssetDict]()
关键修改说明
- 重新定义类型变量顺序和约束,让
T绑定到返回D的AbstractGameObject子类,确保类型关联的正确性 - 将
GameObjects改为双泛型Generic[T, D],显式声明存储的对象类型与返回的字典类型 - 实例化
GameObjects时只需传入对应的GameObject子类和TypedDict类型,无需额外定义容器类
内容的提问来源于stack exchange,提问作者James N
相关产品推荐
相关产品推荐

