跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Python 多重继承的问题 为什么以下代码里 Base 的 __init__ 没有被调用
未分類
21 7 月 2020

Python 多重继承的问题 为什么以下代码里 Base 的 __init__ 没有被调用

Python 多重继承的问题 为什么以下代码里 Base 的 __init__ 没有被调用

資深大佬 : doraemon1293 8

class Base():     def __init__(self):         print("Base")  class First(Base):     def __init__(self):         super().__init__()         print("first")  class Second(Base):     def __init__(self):         print("second")  class Third(First,Second):     def __init__(self):         super().__init__()         print("third") Third() 

为何输出结果为

second

first

third

为什么 First 中 super().init() 没有被调用呢

如果代码改为

class Base():     def __init__(self):         print("Base")  class First(Base):     def __init__(self):         super().__init__()         print("first")  class Second(Base):     def __init__(self):         super().__init__()         print("second")  class Third(First,Second):     def __init__(self):         super().__init__()         print("third") Third() 

则输出结果为

Base

second

first

third

大佬有話說 (10)

  • 資深大佬 : gwy15

    调用 super() 的时候实际上会跟随 MRO 进行链式调用,在这个例子里面,调用链是(从左到右宽度优先搜索)
    `Third` -> `First` -> `Second` -> `Base` -> `object`
    可以用 `Third.mro()` 查看。

    因此,在调用的时候,Third.__init__ 里面 super().__init__() 实际调用的是 Second.__init__(self),而 Second.__init__ 里面没有继续调用 super,所以 Base 的 __init__ 没有调用。

  • 資深大佬 : gwy15

    上面有点笔误
    Third -> First -> Second -/-> Base
    >>> second
    >>> first
    >>> third

  • 資深大佬 : marquina

    @gwy15 更准确地说,Third.__init__里的 super().__init__()调用的是 First.__init__,First.__init__里的 super().__init__调用的是 Second.__init__。

  • 資深大佬 : marquina

    @gwy15 才看到你#2 的回复

  • 主 資深大佬 : doraemon1293

    感谢回答
    两种情况 打印 Third.__mro__ 结果都是
    (<class ‘__main__.Third’>, <class ‘__main__.First’>, <class ‘__main__.Second’>, <class ‘__main__.Base’>, <class ‘object’>)
    多重继承 super 不是从左到右查找吗 为什么会调用 Second.__init__(self)

    我把打印的代码改成标注开始和结束
    “`
    class Base():
    def __init__(self):
    print(“Base”)

    class First(Base):
    def __init__(self):
    print(“first start”)
    super().__init__()
    print(“first end”)
    class Second(Base):
    def __init__(self):
    print(“second start”)
    # super().__init__()
    print(“second end”)

    class Third(First,Second):
    def __init__(self):
    super().__init__()
    print(“third”)
    print(Third.__mro__)
    Third()
    “`
    结果如下
    first start
    second start
    second end
    first end
    third
    为什么 first 先被调用 然而 first 里的 super().__init__()没有任何效果呢?

  • 主 資深大佬 : doraemon1293

    刚看到你的更正 请忽略我上面的回复
    为什么 First.__init__里的 super().__init__调用的是 Second.__init__。
    First 的 super 不应该调用他的父类 Base 吗?

  • 資深大佬 : gwy15

    @doraemon1293 super 是根据 MRO 链走的,不是“父类”。

  • 主 資深大佬 : doraemon1293

    @gwy15
    明白了 一直以为 super 是调用父类 多谢解答

  • 資深大佬 : oahebky

    这是个新式类+钻石继承的问题。

    没有什么特别的东西,就是“规定”。

    具体参见 《 learning Python 》(有中文版)类的高级主题部分 – 第 31 章。

    自认为没有能力解释得比书上更好,所以不多做解释,仅指路。

  • 資深大佬 : gulu

    不如亲自看看 Python 之父当时解决 MRO 的思路:
    http://python-history.blogspot.com/2010/06/method-resolution-order.html?m=1

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具