You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:55:20