ITPub博客

首页 > 应用开发 > Python > python类继承链中 super() 的非直觉行为

python类继承链中 super() 的非直觉行为

原创 Python 作者:tiannuo 时间:2026-05-18 10:49:27 0 删除 编辑

你提到的 Python 类继承链中 super() 的非直觉行为,确实是很多人初学或即使用了一段时间也容易踩坑的地方。我们可以慢慢拆开来看,并通过示例理解它背后的逻辑。


1. super() 并不总是指父类


很多人直觉认为:


class A:

    def f(self):

        print("A")


class B(A):

    def f(self):

        print("B")

        super().f()  # “调用父类 A 的 f”


在这个简单单继承链里,确实是这样,super() 调用的是父类 A 的 f() 方法。


但是在 多重继承 或 菱形继承(diamond inheritance)里,super() 的行为就很容易出乎意料。


2. super() 实际上调用的是 MRO(Method Resolution Order)链上的下一个方法


Python 的类有一个 MRO 顺序,这个顺序决定了 super() 调用的“下一个类”是谁,而不是单纯的父类。


class A:

    def f(self):

        print("A")


class B(A):

    def f(self):

        print("B")

        super().f()


class C(A):

    def f(self):

        print("C")

        super().f()


class D(B, C):

    def f(self):

        print("D")

        super().f()


d = D()

d.f()


输出是:


D

B

C

A

为什么不是你直觉中的 “D → B → A → C” 或其他顺序?

D 的 MRO 是:D → B → C → A → object

可以用 D.__mro__ 或 help(D) 看。

每个 super().f() 实际上调用 MRO 中当前类之后的下一个类的方法,而不是直接调用父类。

所以 B 里的 super().f() 调用的是 MRO 里 B 之后的类 C 的 f 方法,而不是 A。

3. 非直觉场景:多次调用 super() 与构造函数


很多人以为:


class A:

    def __init__(self):

        print("A init")


class B(A):

    def __init__(self):

        print("B init")

        super().__init__()


class C(A):

    def __init__(self):

        print("C init")

        super().__init__()


class D(B, C):

    def __init__(self):

        print("D init")

        super().__init__()


D()


输出:


D init

B init

C init

A init


❌ 注意这里:


每个类都调用了 super().__init__()。

C 的 super().__init__() 不是调用 A 的父类,而是 MRO 中 C 之后的类 A。

A 是最终结束点,object.__init__ 不做任何事。


这在多重继承时非常重要:你可以安全地在每个类里调用 super() 来确保整个继承链都初始化,而不需要知道具体父类是谁。这也是 Python 的 协作式多重继承(cooperative multiple inheritance) 的核心。


4. 一些容易混淆的坑


直接使用父类而非 super()


class B(A):

    def f(self):

        print("B")

        A.f(self)  # 直接调用父类

如果在多重继承中,这会破坏 MRO,可能导致某些类的方法被跳过。

super() 不一定指“上一层父类”

它指 MRO 中当前类之后的下一个类。

在单继承里通常符合直觉,在多继承里必须看 MRO。

使用 super() 时要传 self

Python 3 里,super() 省略参数默认是 super(CurrentClass, self)。

在 Python 2 中,需要写 super(CurrentClass, self).method()。

5. 小结

super() 的目标是调用 MRO 链上的下一个方法,不是简单的“父类方法”。

在多重继承中,super() 让你写的类可以 安全协作,每个类都可以调用 super() 而不关心实际继承链细节。

“非直觉行为”主要出现在多继承和菱形继承模式下,或者当你直接想象 super() 就是父类时。


https://588ku.com/gif/131973829.html https://588ku.com/gif/131973838.html https://588ku.com/gif/131973844.html https://588ku.com/gif/131973850.html https://588ku.com/gif/131973855.html https://588ku.com/gif/131973862.html https://588ku.com/gif/131973867.html https://588ku.com/gif/131973875.html https://588ku.com/gif/131973880.html https://588ku.com/gif/131973886.html https://588ku.com/gif/131973895.html https://588ku.com/gif/131973907.html https://588ku.com/gif/131973916.html https://588ku.com/gif/131973926.html https://588ku.com/gif/131973933.html https://588ku.com/gif/131973940.html https://588ku.com/gif/131973947.html https://588ku.com/gif/131973950.html https://588ku.com/gif/131973955.html https://588ku.com/gif/131973974.html https://588ku.com/gif/131973978.html https://www.51yuansu.com/tupian/2026shijiebeitouzhu13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiwaiwei13388885782.html https://www.51yuansu.com/tupian/2026shijiebeikaihu13388885782.html https://www.51yuansu.com/tupian/2026shijiebeipingtai13388885782.html https://www.51yuansu.com/tupian/2026shijiebeikefu13388885782.html https://www.51yuansu.com/tupian/2026shijiebeidianhua13388885782.html https://www.51yuansu.com/tupian/2026shijiebeixiazhu13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiAPP13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiwangzhan13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiguanwang13388885782.html https://www.51yuansu.com/tupian/2026shijiebeimaiqiu13388885782.html https://www.51yuansu.com/tupian/2026shijiebeipankou13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiwangzhi13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiyaqiu13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiduqiu13388885782.html https://www.51yuansu.com/tupian/2026shijiebeiweixin13388885782.html https://www.51yuansu.com/tupian/maizuqiupingtai13388885782.html https://www.51yuansu.com/tupian/maizuqiudianhua13388885782.html https://www.51yuansu.com/tupian/maizuqiuweixin13388885782.html https://www.51yuansu.com/tupian/maizuqiuwangzhi13388885782.html https://www.51yuansu.com/tupian/maiqiukefu13388885782.html https://www.51yuansu.com/tupian/huangguandaili13388885782.html https://www.51yuansu.com/tupian/huangguanwangzhi13388885782.html https://www.51yuansu.com/tupian/huangguankefu13388885782.html https://www.51yuansu.com/tupian/huangguanxinyong13388885782.html https://www.51yuansu.com/tupian/shoujihuangguan13388885782.html https://www.51yuansu.com/tupian/huangguankahu13388885782.html https://www.51yuansu.com/tupian/huangguanwangzhi13388885782.html https://www.51yuansu.com/tupian/huangguanweixin13388885782.html https://www.51yuansu.com/tupian/huangguanchuzu13388885782.html https://www.51yuansu.com/tupian/xin2chuzu13388885782.html https://www.51yuansu.com/tupian/xin2zuqiu13388885782.html https://www.51yuansu.com/tupian/xin2denglu13388885782.html https://www.51yuansu.com/tupian/xin2wangzhi13388885782.html https://www.51yuansu.com/tupian/xin2weixin13388885782.html https://www.51yuansu.com/tupian/xin2kefu13388885782.html https://www.51yuansu.com/tupian/deng3huangguan13388885782.html https://www.51yuansu.com/tupian/deng3daili13388885782.html https://www.51yuansu.com/tupian/deng3wangzhi13388885782.html https://www.51yuansu.com/tupian/deng3kaihu13388885782.html https://www.51yuansu.com/tupian/deng3kefu13388885782.html

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3171526/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-05-08

  • 博文量
    74
  • 访问量
    66714