Python泛型类部分特化的类型标注问题及正确声明方式
泛型类层级的类型注解问题
我有一个泛型类层级结构,类型参数也对应有层级关系,现在要给这些类添加正确的类型注解。尝试对Root类做部分特化时遇到了mypy报错:
原代码
from typing import Generic, TypeVar _T = TypeVar("_T") class Root(Generic[_T]): def __init__(self, value: _T): self.value = value _Number = TypeVar("_Number", int, float) class FooNumber(Root[_Number]): def __init__(self, value: _Number): super().__init__(value)
mypy报错信息
test-mypy-typevar-inherit.py:13: error: Argument 1 to "__init__" of "Root" has incompatible type "int"; expected "_Number" [arg-type] test-mypy-typevar-inherit.py:13: error: Argument 1 to "__init__" of "Root" has incompatible type "float"; expected "_Number" [arg-type]
我的目标是让FooInt继承自FooNumber[int],FooFloat继承自FooNumber[float]。直接从Root[int]特化FooInt没问题,但不清楚FooNumber的定义为什么会引发错误。
正确的声明方式
问题出在FooNumber没有显式继承Generic[_Number]。当用带约束的TypeVar作为父类的类型参数时,mypy无法正确推断父类__init__方法的参数类型与子类TypeVar的关联,需要让FooNumber自身也成为泛型类,明确声明它的类型参数。
修正后的代码:
from typing import Generic, TypeVar _T = TypeVar("_T") class Root(Generic[_T]): def __init__(self, value: _T): self.value = value _Number = TypeVar("_Number", int, float) # 让FooNumber同时继承Generic[_Number]和Root[_Number] class FooNumber(Generic[_Number], Root[_Number]): def __init__(self, value: _Number): super().__init__(value) # 现在可以正常定义子类 class FooInt(FooNumber[int]): pass class FooFloat(FooNumber[float]): pass # 验证类型正确性 foo_int = FooInt(42) foo_float = FooFloat(3.14)
这样修改后,mypy就能正确识别FooNumber的类型参数,调用父类__init__时不会再报错,同时也能实现FooInt、FooFloat基于FooNumber的特化需求。
内容的提问来源于stack exchange,提问作者Yann Dirson
相关产品推荐
相关产品推荐

