欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-21 11:25:43
...

前言

  • 该文大白话解释,如不专业,请多包涵。
  • 调用父类方法有三种方式:
    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。所以不推荐使用
  • 此文只写到“儿子”辈儿,其实写到“孙子”辈儿就可以理解的更透彻了,但是本文旨在通俗理解多继承中的一些坑,如果想要更全面的了解的话,可以自己写一下代码,或者参考一下别人的博文。