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

如何为Python类工厂添加类型标注以通过mypy检查?

解决mypy对工厂函数返回类作为基类的类型检查错误

你写的代码运行正常,但mypy报错的核心原因是:mypy将FooA视为普通变量,而非合法的类型标识。Python允许变量在运行时被重新赋值,mypy无法保证FooA在定义FooB时仍然是有效的类类型,因此会抛出"Variable is not valid as a type"和"Invalid base class"这两个错误。

以下是几种可行的解决方法:

方案1:用TypeAlias显式标注类型别名

在Python 3.9+中,使用typing.TypeAlias明确告诉mypy,FooA是一个类型别名而非普通变量,这是最清晰规范的解决方式:

from abc import ABC
from typing import Type, TypeAlias


class AbstractFoo(ABC):
    """Abstract foo."""
    foo_attr: int


def foo_factory(foo_attr_val: int) -> Type[AbstractFoo]:
    class Foo(AbstractFoo):
        foo_attr = foo_attr_val
    return Foo


# 显式标注FooA为类型别名
FooA: TypeAlias = foo_factory(5)


class FooB(FooA):
    """Public concrete foo."""

print(FooB.foo_attr)

方案2:用cast强制类型转换

如果你不想使用类型别名,可以通过cast强制告诉mypy,FooA确实是符合要求的类类型,以此绕过检查:

from abc import ABC
from typing import Type, cast


class AbstractFoo(ABC):
    """Abstract foo."""
    foo_attr: int


def foo_factory(foo_attr_val: int) -> Type[AbstractFoo]:
    class Foo(AbstractFoo):
        foo_attr = foo_attr_val
    return Foo


# 强制转换类型,让mypy识别FooA为合法类型
FooA = cast(Type[AbstractFoo], foo_factory(5))


class FooB(FooA):
    """Public concrete foo."""

print(FooB.foo_attr)

修改后重新运行mypy foo.py,错误会被消除,代码也能保持正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:10:24