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

Python 3.11多继承模型类型注解实现与mypy类型推断问题

解决共享元类关联类的Mypy类型推断问题

问题场景

我们有一组共享元类AMeta的关联类,核心结构包括:

  • 抽象类A,元类型为AMeta
  • 抽象类ADerived,同时继承自A和另一个类C

在此基础上,会动态创建ADerived的实现类(比如D1、D2),以及A的实现类(比如E、F)。A的每个实现类都有一个类变量_DerivedModel,指向对应的ADerived子类,但目前Mypy无法正确推断该变量的具体类型。

简化后的示例代码如下:

from __future__ import annotations
from typing import TypeVar, Type, ClassVar

_BModel = TypeVar("_BModel", bound="ADerived")


class C:
    pass


class AMeta(type):
    @property
    def BModel(cls: Type[A]) -> Type[_BModel]:
        return cls._DerivedModel


# Abstract Models
class A(metaclass=AMeta):
    _DerivedModel: ClassVar[Type[_BModel]]


class ADerived(A, C):
    pass


# Derived Models (this models are dynamically created)
class D1(ADerived):
    pass


class D2(ADerived):
    pass


# Implementations


class E(A):
    _DerivedModel = D1


class F(A):
    _DerivedModel = D2


MyDerived1 = E.BModel  # 期望Mypy推断为type[D1]
MyDerived2 = F.BModel  # 期望Mypy推断为type[D2]

解决方法

要让Mypy正确追踪_DerivedModel的具体类型,需要把A定义为泛型类,让每个A的子类绑定对应的ADerived子类。具体修改如下:

from __future__ import annotations
from typing import TypeVar, Type, ClassVar, Generic

# 定义绑定到ADerived的TypeVar
_BModelT = TypeVar("_BModelT", bound="ADerived")


class C:
    pass


class AMeta(type):
    # 调整类型注解,适配泛型类的类型
    @property
    def BModel(cls: Type[A[_BModelT]]) -> Type[_BModelT]:
        return cls._DerivedModel


# 将A改为泛型类,继承Generic
class A(Generic[_BModelT], metaclass=AMeta):
    # 类变量类型绑定到泛型参数
    _DerivedModel: ClassVar[Type[_BModelT]]


class ADerived(A[_BModelT], C):
    pass


# 动态创建的实现类保持不变
class D1(ADerived):
    pass


class D2(ADerived):
    pass


# 实现类会自动推断泛型参数,也可以显式指定比如E(A[D1])
class E(A):
    _DerivedModel = D1


class F(A):
    _DerivedModel = D2


# 现在Mypy可以正确推断类型:MyDerived1是Type[D1],MyDerived2是Type[D2]
MyDerived1 = E.BModel
MyDerived2 = F.BModel

关键修改点

  • 将A改为泛型类,继承Generic[_BModelT],让每个子类都能关联具体的ADerived子类类型
  • 元类AMeta的BModel属性中,将cls的类型注解改为Type[A[_BModelT]],确保返回值和泛型参数一致
  • A中的_DerivedModel类变量类型绑定到泛型参数_BModelT,让Mypy能追踪每个子类的具体赋值

内容的提问来源于stack exchange,提问作者Bravhek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:08:22