Python中继承ABC的子类调用super().__init__()为何能正常工作
核心原因
这个现象的本质是对super()的作用机制存在认知偏差:super()从来不会创建父类的实例,你之前的假设从根上就不成立。
两个基础前提
先把两个规则理清楚,就很容易想明白:
- 抽象基类(ABC)禁止直接实例化的校验,只在你直接调用抽象类构造方法(也就是明写
A()要创建一个A类对象)的时候才会触发。这个校验是ABC的元类实现的,仅拦截类的直接实例化行为,不会限制你调用类内部定义的普通方法。 - 当你写
B()实例化子类的时候,整个流程从始至终只会创建一个B类的实例对象,内存里不会凭空生成一个独立的、和B实例没关系的父类A实例。
super().__init__()到底做了什么
在B的__init__里调用super().__init__()时,实际执行流程是:
super()返回一个特殊的代理对象,这个代理从一开始就绑定了当前正在初始化的那个B类实例- 代理会顺着类的方法解析顺序(MRO)找到父类A里写的
__init__方法 - 把之前绑定的B类实例作为
self参数,传给A的__init__方法执行——效果和你手动写A.__init__(self)差不多,区别是super会自动处理多继承场景的调用顺序,避免重复调用父类方法。
整个过程里你从来没写过A()去尝试创建A的实例,只是借A类里写好的初始化逻辑,给已经存在的B实例挂属性(比如你代码里的self.file_manager = FileManager(),这里的self从始至终都是B类的实例),当然不会触发抽象基类的实例化拦截。
你可以自己加一行代码验证:在A的__init__里写print(type(self)),实例化B的时候会输出<class 'B'>,直接证明执行A的初始化逻辑时,操作的一直是子类实例。
相关代码示例
抽象基类A定义
from abc import ABC, abstractmethod from util.fileManager import FileManager class A(ABC): def __init__(self): self.file_manager = FileManager() # 组合引入的文件管理器对象 # 取消下面注释即可验证self的实际类型 # print(type(self)) # 抽象方法定义 @abstractmethod def business_logic(self): pass
实现类B定义
from interfaces.A import A class B(A): def __init__(self): super().__init__() def business_logic(self): # 实现抽象类定义的接口方法 pass
补充说明:如果想深入了解super的完整运行逻辑,可以查阅Python官方文档中关于super类型、方法解析顺序(MRO)的相关说明。
内容的提问来源于stack exchange,提问作者Mowgli
相关产品推荐
相关产品推荐

