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

Python文档中__init_subclass__示例的Mypy报错解决问询

解决mypy无法识别__init_subclass__添加的类属性问题

针对你遇到的mypy报错问题,有几种可行的解决方式:

方法一:在父类中添加类属性类型注解

在Philosopher类中显式声明default_name为类级别的类型注解,让mypy明确知道所有子类都会拥有这个属性:

from typing import ClassVar

class Philosopher:
    default_name: ClassVar[str]  # 声明类属性类型
    def __init_subclass__(cls, /, default_name: str, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    pass

# 此时mypy会正确识别AustralianPhilosopher.default_name
print(AustralianPhilosopher.default_name)

方法二:使用typing.Protocol定义子类契约

如果希望更严格地约束子类必须包含default_name属性,可以定义一个协议,让子类遵循该契约:

from typing import Protocol, ClassVar

class HasDefaultName(Protocol):
    default_name: ClassVar[str]

class Philosopher:
    def __init_subclass__(cls, /, default_name: str, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    default_name: ClassVar[str]  # 显式实现协议要求的属性

# 类型检查时,mypy会确认子类符合协议
def greet_philosopher(philosopher_cls: type[HasDefaultName]) -> str:
    return f"Hello, {philosopher_cls.default_name}!"

print(greet_philosopher(AustralianPhilosopher))

方法三:使用mypy的# type: ignore临时忽略(不推荐)

如果只是临时绕过检查,可以在访问属性的地方添加忽略注释,但这会丢失类型检查的优势,仅建议在特殊场景下使用:

class Philosopher:
    def __init_subclass__(cls, /, default_name: str, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    pass

# 添加忽略注释
print(AustralianPhilosopher.default_name)  # type: ignore

最推荐方法一,它既简洁又能让mypy准确识别类属性的存在,符合类型检查的最佳实践。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:40:35