如何为返回泛型基类派生类字典的函数添加类型提示
问题解决方案:为解析器类字典添加准确的类型提示
核心问题在于你需要表示解析器类的类型(而非实例),且这些类都是泛型BaseSectionParser的子类。以下是具体的实现方案:
步骤1:调整泛型参数与导入必要类型
首先确保泛型参数支持协变,让子类解析器能适配父类泛型类型,并导入Type(用于标记类的类型):
from dataclasses import dataclass from typing import TypeVar, Generic, Optional, Type, Dict, abstractmethod # 标记T为协变,允许子类解析器适配父类泛型类型 T = TypeVar("T", bound=BaseSection, covariant=True) @dataclass class BaseSection: extra: int = 0 @dataclass class ASection(BaseSection): a: int = 0 @dataclass class BSection(BaseSection): b: int = 0 class BaseSectionParser(Generic[T]): def parse(self, data: str) -> Optional[T]: if len(data) == 0: return None return self._get_data(data) @abstractmethod def _get_data(self, data: str) -> T: pass class ASectionParser(BaseSectionParser[ASection]): def _get_data(self, data: str) -> ASection: ret = ASection() if data == "a": ret.a = 1 return ret class BSectionParser(BaseSectionParser[BSection]): def _get_data(self, data: str) -> BSection: ret = BSection() if data == "b": ret.b = 2 return ret
步骤2:为get_parsers添加准确类型提示
使用Type[BaseSectionParser[BaseSection]]作为字典值的类型,明确表示值是任意BaseSectionParser子类的类型:
def get_parsers() -> Dict[str, Type[BaseSectionParser[BaseSection]]]: return { "a": ASectionParser, "b": BSectionParser, }
方案说明
Type[X]用于标记“X类的类型”,对应你返回的解析器类(而非实例),解决了之前混淆类和实例类型的问题。- 协变的
TypeVar允许BaseSectionParser[ASection]这类子类解析器被视为BaseSectionParser[BaseSection]的子类型,因此Type[ASectionParser]可以完美适配Type[BaseSectionParser[BaseSection]]。 - 该类型提示既通过Mypy的类型检查,又准确表达了字典的结构:键为字符串,值为任意
BaseSectionParser派生类的类型。
可选优化:类型别名
如果需要重复使用该类型,可以定义一个别名简化代码:
ParserClass = Type[BaseSectionParser[BaseSection]] def get_parsers() -> Dict[str, ParserClass]: return { "a": ASectionParser, "b": BSectionParser, }
内容的提问来源于stack exchange,提问作者Mauricio
相关产品推荐
相关产品推荐

