python 多重继承和方法解析顺序 - Go语言中文社区

python 多重继承和方法解析顺序


python 支持多继承:
任何实现多重继承的语言都要处理潜在的命名冲突,这种冲突由不相关的祖先类实现同名 方法引起。这种冲突称为“菱形问题”,如图 12-1 和示例 12-4 所示。
在这里插入图片描述
示例代码:

"""
python 中多继承:
"""
import pysnooper


class A:
    @pysnooper.snoop()
    def ping(self):
        print('A_ping:', self)


class B(A):
    @pysnooper.snoop()
    def pong(self):
        print('B_pong:', self)


class C(A):
    @pysnooper.snoop()
    def pong(self):
        print('C_PONG:', self)


class D(B, C):
    def ping(self):
        # 这里的super() 是调用B类
        super().ping()
        print('D_post-ping:', self)

    def pingpong(self):
        # 这里自身方法的调用,解析顺序和刚才一样
        self.ping()
        # 这里的super() 是调用B类
        super().ping()
        # 先查找自身,在查找B,在查找C,最后才会查找A
        self.pong()
        # 这里的super() 是调用B类
        super().pong()
        # 这里是调用C类方法
        C.pong(self)


if __name__ == "__main__":
    d = D()
    # 先查找自身,在查找B,在查找C,最后才会查找A
    d.pong()  # 依次放开,通过 pysnooper 可以看到执行顺序
    # d.ping()  # 依次放开,通过 pysnooper 可以看到执行顺序
    # d.pingpong()  # 依次放开,通过 pysnooper 可以看到执行顺序

1,放开 d.pong() 结果:
在这里插入图片描述
2,放开 d.ping() , 注释 d.pong(),结果:
在这里插入图片描述
3,放开 d.pingpong() , 注释 d.pong()d.ping() 结果:
在这里插入图片描述
当然也可以像下图的调用方式(超类中的方法都可以直接调用,此时要把实例作为显式参数传入。):
在这里插入图片描述
Python 能区分 d.pong() 调用的是哪个方法,是因为 Python 会按照特定的顺序遍历继承图。 这个顺序叫方法解析顺序(Method Resolution Order,MRO)。类都有一个名为 __mro__ 的 属性,它的值是一个元组,按照方法解析顺序列出各个超类,从当前类一直向上,直到 object 类。D 类的 __mro__ 属性如下:
在这里插入图片描述
若想把方法调用委托给超类,推荐的方式是使用内置的 super() 函数。在 Python 3 中,这 种方式变得更容易了,如示例 中 D 类的 pingpong 方法所示。然而,有时可能需要绕 过方法解析顺序,直接调用某个超类的方法——这样做有时更方便。如图:
在这里插入图片描述
注意,直接在类上调用实例方法时,必须显式传入 self 参数,因为这样访问的是未绑定方法(unbound method)。

在这里插入图片描述
然而,使用 super() 最安全,也不易过时。调用框架或不受自己控制的类层次结构中的方 法时,尤其适合使用 super()。使用 super() 调用方法时,会遵守方法解析顺序。

方法解析顺序不仅考虑继承图,还考虑子类声明中列出超类的顺序。也就是说,如果在 上面的代码中把 D 类声明为 class D(C, B):,那么 D 类的 __mro__ 属 性就会不一样:先搜索 C 类,再搜索 B 类。

查看几个类的 __mro__ 属性
在这里插入图片描述
在这里插入图片描述

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/MZP_man/article/details/100029715
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 21:27:12
  • 阅读 ( 1005 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢