返回字典值源自泛型基类的类型提示
背景
我正在写一个系统,用来解析一个包含不同部分的配置文件。每个部分可以有一系列条目,每个条目都有不同的逻辑来解析配置文件中的数据。我把每个部分封装成一个类(这些类都是从一个基础部分类派生的)。对于每个部分类,我还有一个配套的解析器类,它充当该特定部分的工厂。所以每个解析器会接收加载的配置文件,解析它的部分,并返回相应的部分类类型。
为了让用户能够在文件中添加更多部分或覆盖基础部分,我需要返回一个包含所有基础解析器的表。这个想法是,用户可以为他们的自定义部分添加更多解析器,或者通过从中派生并根据需要修改解析代码来覆盖特定的解析器。这也可以包括从原始部分返回一个派生类。为此,我需要返回一个字典,将每个解析器的名称映射到相应的解析器。现在我遇到的问题是,如何正确地为这个函数添加类型提示。
最小示例
下面是我想做的一个简化示例。首先是部分类:
@dataclass
class BaseSection:
extra: int = 0
@dataclass
class ASection(BaseSection):
a: int = 0
@dataclass
class BSection(BaseSection):
b: int = 0
现在是解析器:
T = TypeVar("T", bound=BaseSection)
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
最后,这是返回字典的函数:
def get_parsers() -> dict: # <- What do I put here for a type hint?
return {
"a": ASectionParser,
"b": BSectionParser,
}
我尝试过的事情
到目前为止,我尝试了以下类型提示:
dict
、dict[str, Any]
、dict[str, type]
:这些是最简单的选项。Mypy没有报错,但显然它们没有提供关于返回的字典是什么的信息。我知道这些可以用,但我在想是否有更好的方式来添加类型提示。dict[str, BaseSectionParser]
:Mypy对这两行给出了相同的错误error: Dict entry 0 has incompatible type "str": "type[ASectionParser]"; expected "str": "BaseSectionParser[Any]"
dict[str, BaseSectionParser[T]]
:Mypy也给出了错误,唯一的区别是它把Any
参数改成了T
。
老实说,我对该怎么做感到困惑。我该如何为这个函数添加类型提示,以传达它返回的是“一个字符串到从BaseSectionParser派生的类型的字典”这一概念呢?
编辑 1
扩展了尝试的类型提示,从dict
到包括dict[str, type]
和dict[str, Any]
1 个回答
2
这个怎么样呢?
def get_parsers() -> dict[str, type[ASectionParser] | type[BSectionParser]]:
return {
"a": ASectionParser,
"b": BSectionParser,
}
或者...
def get_parsers() -> dict[str, type[BaseSectionParser]]:
return {
"a": ASectionParser,
"b": BSectionParser,
}
这两种选择都会给你正确的类型提示,并且不会出现任何错误。