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

为何已在子类实现抽象类属性,中间类仍需定义该属性?

问题解答

核心原因:Python抽象类的检查时机

Python的abc模块有个关键规则:当你定义一个继承抽象类的子类时,如果这个子类不是抽象类,就必须立刻实现父类所有的抽象成员——这个检查在类定义完成时就会执行,不是等到实例化最终子类的时候。

你定义的InterClass继承了AbcClass,但没实现MAP,也没把自己标记为抽象类,那Python就会认为InterClass是一个“不完整”的非抽象类,违反了抽象类的契约。哪怕你在ConcreteClass里补了MAP,但InterClass本身的抽象状态已经有问题了,所以实例化时还是会报错。

为什么要这么设计?

抽象类的核心作用就是给子类定规矩:所有继承它的非抽象子类,必须实现约定好的抽象成员。如果允许中间类跳过去实现,那这个中间类本身就成了一个“不合格”的子类——它既不是抽象类(不能用来约束子类),又没遵守父类的规矩,这就违背了抽象类的设计初衷。

解决办法

有两种简单的处理方式:

  1. 让InterClass保持抽象类状态:不需要在InterClass里定义MAP,只要它继承了抽象类但没实现所有抽象成员,Python会自动把它当成抽象类,把实现MAP的责任交给它的子类。修改后的InterClass就是你注释掉MAP = None的样子,直接用就行:
class InterClass(AbcClass):
    @property
    def text(self) -> str:
        return "text"

此时InterClass是抽象类,Python不会要求它实现MAP,只会检查最终的ConcreteClass是否完成了所有抽象成员的实现。

  1. 在InterClass里重新声明抽象MAP:如果你想更清晰地传递抽象契约,可以在InterClass里重新定义MAP为抽象属性,明确告诉子类必须实现它:
class InterClass(AbcClass):
    @classmethod
    @property
    @abstractmethod
    def MAP(cls) -> Dict[str, str]:
        raise NotImplementedError

    @property
    def text(self) -> str:
        return "text"

这样InterClass依然是抽象类,直到ConcreteClass实现MAP后才能被实例化。

验证修改后的代码

用第一种方案的完整代码示例:

from abc import ABC, abstractmethod
from typing import Dict

class AbcClass(ABC):
    @classmethod
    @property
    @abstractmethod
    def MAP(cls) -> Dict[str, str]:
        raise NotImplementedError

    @property
    def map(self) -> Dict[str, str]:
        return self.MAP

class InterClass(AbcClass):
    @property
    def text(self) -> str:
        return "text"

class ConcreteClass(InterClass):
    MAP = {
        "a": "b"
    }

c = ConcreteClass()
print(c.map)  # 输出: {'a': 'b'}

运行这段代码就不会再触发NotImplementedError了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:52:04