前言
- 该文大白话解释,如不专业,请多包涵。
- 调用父类方法有三种方式:
1、类名.方法(self) # 此处没有代码说明,在文末有益于理解的文字说明(不推荐)
2、super().方法名 # 和下面一种调用方法一样(常用)
3、super(类名,self).方法名
ps:为什么要有self这个参数?仅供参考的理解是:将自己作为实参传递给这个继承的类中,才能执行对应方法的代码。
- 类名.__mro__是依照C3算法衍生出来的一个类的属性,该属性的特点是:
1、使所有继承的类只执行一次。
2、返回一个元祖,元祖中是使用super()方法时调用父类方法的顺序。(顺序是:拿着类名去元祖里面找,找到了之后,便去执行它的“下一个”对应的类中对应的方法) - 总的来说,py2继承顺序是深度优先,py3是广度优先,关于深度优先和广度优先请相关链接:链接一 链接2 链接3。
代码1
class P(object):
def __init__(self):
print("---测试---\r\n")
class S1(P):
def __init__(self):
print("--开始S1--")
super(S1, self).__init__()
print("我是S1的__mro__:", S1.__mro__)
a = S1()
代码2
class P(object):
def __init__(self):
print("---测试---\r\n")
class S1(P):
def __init__(self):
print("--开始S1--")
super(S1, self).__init__()
class S2(S1):
def __init__(self):
print("--开始S2--")
super(S2, self).__init__()
super(S1, self).__init__()
super(P, self).__init__()
print("我是S1的__mro__:", S1.__mro__)
print("我是S2的__mro__:", S2.__mro__,"\r\n")
a = S1()
b = S2()
补充
- 重写不等于重载,关于重载在python中是极少的,可以忽略不记(比如运算符 ‘+’ 是用了重载)。重载是什么?简单理解:对于一个相同的变量名的函数,传入不同数据类型的参数,可以精确的调用该函数进行操作的过程。
- 多继承中的“类名.方法”的方式在此文没有解释。为什么呢?
1、python3基本上要把它淘汰了。
2、为什么要淘汰?:它的机制你可以理解为:如果“孙子”类有俩“爸爸”类,他的两个“爸爸”类在自己的某一个方法中方法中都调用了“爷爷”类的那个方法,当调用两个“爸爸”类中的这个方法时,而于是就造成了爷爷的代码被调用了多次。一方面太冗余,另一方面可能出现不必要的bug,而如果使用的是super()方式的话,会按照__mro__属性的顺序来调用,就不存在这方面的问题。所以类名.的方式不推荐使用。 - python2的深度优先的弊端是什么?
- 爸爸辈们的方法还没执行呢,直接执行了爷爷辈,这合适吗?
- 此文只写到“儿子”辈儿,其实写到“孙子”辈儿就可以理解的更透彻了,但是本文旨在通俗理解多继承中的一些坑,如果想要更全面的了解的话,可以自己写一下代码,或者参考一下别人的博文。