Python 现代开发学习笔记

(九)super() 与方法解析顺序

只看单继承时,容易把 super() 理解为“固定访问代码里写出的父类”。多个类一起参与继承时,它的含义要沿方法解析顺序(MRO)阅读。

# 两个中间类都把当前对象的调用继续交给 MRO 中的下一个实现。
class Root:
    def describe(self):
        return ["Root"]


class Labelled(Root):
    def describe(self):
        return ["Labelled"] + super().describe()


class Tracked(Root):
    def describe(self):
        return ["Tracked"] + super().describe()


class Combined(Labelled, Tracked):
    pass


print([cls.__name__ for cls in Combined.__mro__])
print(Combined().describe())

输出:

['Combined', 'Labelled', 'Tracked', 'Root', 'object']
['Labelled', 'Tracked', 'Root']

__mro__ 保存实际查找顺序,object 是普通 Python 类最终继承到的基类。调用先在 Labelled 找到实现;其中的 super() 从 Labelled 在这个实例 MRO 中的位置之后继续,下一站是 Tracked,再从 Tracked 继续到 Root。

沿同一实例的 MRO 向后调用并逐层合并结果

因此 Labelled 中的 super() 在这次调用里找到了 Tracked,而不是它定义处直接写出的 Root。整条调用链保持同一个实例;每一层再决定是否继续调用下一层。读到已有代码的多重继承时,先列出 __mro__,再逐条跟踪调用,返回时合并各层结果。super 的查找规则

普通业务记录用单继承或组合就能表达的关系,可以直接按那种方式组织。引入多个基类时,需要把共同方法的参数和继续调用方式一起安排好,避免只看类名就猜执行顺序。

笔记正文与全部题解 · Ctrl / ⌘ K