浅析:python多继承中三个重写父类方法的方式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/rusi__/article/details/97560438

前言

  • 该文大白话解释,如不专业,请多包涵。
  • 调用父类方法有三种方式:
    1、类名.方法(self)
    2、super().方法名
    3、super(类名,self).方法名
    ps:为什么要有self这个参数?仅供参考的理解是:将自己作为实参传递给这个继承的类中,才能执行对应方法的代码。
  • 多继承中的“类名.方法(self)”的方式在此文没有解释,但是在最后面的补充中有一段个人觉得非常容易理解的说明(还有关于一些小的方面的知识点)。

  • 如果只是想简单理解以下super()及super(类名,self)的,看代码1及输出即可。(输出写入代码最后的注释上。)
  • 类名.__mro__是依照C3算法衍生出来的一个类的属性,该属性的特点是:
    1、使所有继承的类只执行一次。
    2、返回一个元祖,元祖中是使用super()方法时调用父类方法的顺序。(顺序是:拿着类名去元祖里面找,找到了之后,便去执行它的“下一个”对应的类中对应的方法

代码1

class P(object):
    def __init__(self):
        print("---测试---\r\n")


class S1(P):
    def __init__(self):
        print("--开始S1--")
        # super().__init__() # 默认是自己的类名,所以等同super(S2, self).__init__()
        super(S1, self).__init__()


print("我是S1的__mro__:", S1.__mro__)
a = S1()


# todo 输出为:
# 我是S1的__mro__: (<class '__main__.S1'>, <class '__main__.P'>, <class 'object'>)
# # --开始S1--
# # ---测试---

代码2

class P(object):
    def __init__(self):
        print("---测试---\r\n")


class S1(P):
    def __init__(self):
        print("--开始S1--")
        # super().__init__()
        super(S1, self).__init__()


class S2(S1):
    def __init__(self):
        print("--开始S2--")
        # super().__init__()  # 默认是自己的类名,所以等同super(S2, self).__init__()
        super(S2, self).__init__()  # 根据__mro__,它会去执行S1中的__init__()。
        super(S1, self).__init__()  # 根据__mro__,它会去执行P中的__init__(),所以没有了  "--开始S1--"。
        super(P, self).__init__()  # 执行了,但是执行的是  <class 'object'> 所以没数据。


print("我是S1的__mro__:", S1.__mro__)
print("我是S2的__mro__:", S2.__mro__,"\r\n")


a = S1()
b = S2()

# todo 输入为:
# 我是S1的__mro__: (<class '__main__.S1'>, <class '__main__.P'>, <class 'object'>)
# 我是S2的__mro__: (<class '__main__.S2'>, <class '__main__.S1'>, <class '__main__.P'>, <class 'object'>)
#
# --开始S1--
# ---测试---
#
# --开始S2--
# --开始S1--
# ---测试---
#
# ---测试---

补充

  • 重写不等于重载,关于重载在python中是极少的,可以忽略不记(比如运算符 ‘+’ 是用了重载)。重载是什么?简单理解:对于一个相同的变量名的函数,传入不同数据类型的参数,可以精确的调用该函数进行操作的过程。
  • 多继承中的“类名.方法”的方式在此文没有解释。为什么呢?
    1、python3基本上要把它淘汰了。
    2、它的机制你可以理解为:如果“孙子”类调用父类中的方法,然后孙子有两个“爸爸”,而他两个“爸爸”在这个被调用的方法中都调用了爷爷的那个方法,于是就造成了爷爷的代码被调用了多次。一方面太冗余,另一方面可能出现不必要的bug。所以不推荐使用
  • 此文只写到“儿子”辈儿,其实写到“孙子”辈儿就可以理解的更透彻了,但是本文旨在通俗理解多继承中的一些坑,如果想要更全面的了解的话,可以自己写一下代码,或者参考一下别人的博文。

猜你喜欢

转载自blog.csdn.net/rusi__/article/details/97560438