面试:MRO问题 (理解笔记)

版权声明:欢迎copy,只求有用 https://blog.csdn.net/muzhe1024/article/details/86072989

MRO在面向对象编程中是很重要的思想,也是很多新手难以理解的牛角尖,下面谈谈我的理解,希望抛砖引玉.

场景:
面试题:什么是MRO
答:MRO是单词的简写,是指方法解析顺序

那你怎么理解MRO?
答:MRO主要是指在支持继承编程语言中方法解析的顺序,是靠算法(函数)计算出来的,是人为规定的,就是一种规则.

那就python来说的MRO顺序是怎样的?
答:你是说py2还是py3?他们中的MRO顺序是不一样的哦?

都说一说.
答:我一般都用py3,所以py2简单说一下(幸好他不问py2,哈哈…)

ok开始:
假定大家都是知道什么是继承,在编程语言中,继承是有顺序的,因为代码是一行一行执行的,如果是单继承,没问题,但是多继承就有可能混乱,比方说我继承了a,又继承了b,a和b中都有同名的方法,我调用方法时候,是调用a的还是b的,就规定了一种顺序.
其实严格上来说py2和py3不足以划分MRO的分界,这个顺序严格上是以PY2.3为分界的(),在py2.3以前,经典类没有本源,遵循的是深度解析的原则,就是不管继承关系有多混乱,解释器会找到你最先继承的谁的.但是这是不合理的,人类的进化是以知识的迭代为基础的,如果新的知识优于旧的知识(别跟我杠什么是新什么是旧,什么优什么不优),那我们就应该接受新的知识,也就是说为什么要继承,其目的是为了达到最先进的选择从而节省更新成本,所以从py2.3开始,规定了所有类的本源必须是object引入了新的C3(类似于拓扑)算法实现新的MRO,他的原则是局部优先.也就是说继承离你上一代亲人的方法.
代码:
在这里插入图片描述

这个算法实现的原理是,将class后面的括号()里的类顺序,按照从本身开始,从左到右的顺序进行单独遍历,如果他们有中有很混乱的继承,就按遍历的结果取出第一个拿到的类,以此类推,直道最终的object类,
算法如图:
在这里插入图片描述
代码如图:
在这里插入图片描述

需要注意的是,py3的MRO规定中,你不能写出二义性的类,会报错.
代码检测如图:
在这里插入图片描述

所以,MRO简单来说就被规定成了按照书写顺序从左到右继承了.写代码的时候就要按照规范,从self开始,写到最后的object.

面试官:
那py3中既然规定了调用顺序,怎么实现更老父类的方法的调用?
答:super啊!!(当然还能直接类名调用)
总结:
1,MRO保证了多继承情况 每个类只出现一次
2,super().__init__相对于类名.init,在单继承上用法基本无差
3,但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次
4,多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错
5,单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错
6,多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍, 而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因

下面是一个小练习:

class Parent(object):
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)

答案:

1 1 1
1 2 1
3 2 3

这里比较容易混的就是,继承----调用----重写 的含义,总结起来 继承是为了调用,但是重写了,就不继承了 !!!

(抛砖引玉,不喜请忽略)

个人公众号,没事看看可以(关于父子故事的)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/muzhe1024/article/details/86072989
MRO