浅谈Python多继承与(Pthony2、3)搜索顺序的变化——面试必备

浅谈Python多继承与(Pthony2、3)搜索顺序的变化

一、Pyhton的多继承

说到面向对象的三大特性:封装、继承、多态。今天我们聊到的是Pyhton中的多继承,与Java语言不同的是,Pyhton它是支持多继承的,怎么说呢?(一个儿子可以有多个爹,哈哈。)

接下来先简单的代码实现下:

class A:
    def test(self):
        print('AAAAAA')

class B:
    def test1(self):
        print('BBBBBB')

class C(A,B):  #C同时继承了A,B两个父类
    pass

c = C()
c.test()
c.test1()

执行结果如下:

AAAAAA

BBBBBB

可以看到,C同时继承了A,B两个父类,也可以调用到父类的方法。这就是python的多继承。

二、多继承的搜索顺序

那既然可以多继承,我们就要考虑到,比如在两个父类中,有同名方法,那么在我子类中会去怎么调用呢?哪个优先级高呢?

class Base:  #爷爷类(针对于D)
    def test(self):
        print('Base')
class A(Base):  #爸爸类1(针对于D)
    def test(self):
        print('AAAAAA')

class B(Base):  #爸爸类2(针对于D)
    def test(self):
        print('BBBBBB')

class C(Base): #爸爸类3(针对于D)
    def test(self):
        print('CCCCCC')

class D(A,B,C):  
    pass

d =D()
d.test()

执行结果如下:

AAAAAA

可以看到,它先搜索到的是父类A,也就是继承的第一个类。由此可以看出它的搜索顺序是从左至右。在这里,我们可以引入一个模块inspect,它的作用是可以帮助我们看到我们多继承的顺序,接下来去看看这个模块。

import inspect
print(inspect.getmro(D))

接上面的代码我们导入inspect模块,调用它的getmro(cls)方法,传入我们的子类D。得到的结果如下:

(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>)

它返回了一个元组,里面是D在多继承之后它的搜索顺序。D-->A-->B-->C-->object

查看inspect的底层我们可以看到,它实际上是用了魔术方法__mro__,那其实我们也可以直接通过print(D.__mro__)得到同样的结果。

三、深度优先与广度优先

接下来我们继续探究,会提到两个概念:深度优先,广度优先以及它在pthon2和python3的区别。

从Python2.2开始,Python 引入了 new style class(新式类),它和经典类区别就在于定义类的时候形式上多了个(object),具体区别后面我会专门写出来,在这主要理解多继承。

#经典类
class P1:   #新式类class P1(object):
    def foo(self):
        print('P1-foo')

class P2:
    def foo(self):
        print('P2-foo')

    def bar(self):
        print('P2-bar')

class C1(P1,P2):
    pass

class C2(P1,P2):
    def bar(self):
        print('C2-bar')

class D(C1,C2):
    pass

d = D()
print(D.__mro__)
d.foo()
d.bar()

D作为最新类来讲,P1,P2作为爷爷类,C1,C2作为父类。那么它在经典类(pyhton2)中的搜索顺序就是:

                        D-->C1-->P1-->P2-->C2    我们称之为深度优先。

我的理解是它找完自己之后从左至右开始找第一个父类C1,再去从左至右深入找C1的父类P1,P2。然后返回来再找第二个父类C2。

那么它在新式类(python3)中的搜索顺序就是:

                        D-->C1-->C2-->P1-->P2    我们称之为广度优先。

我的理解是它找完自己之后先从左至右找自己的父类C1,C2。再去从左至右找C1的父类P1,P2。

那按照python3的执行结果如下:

当然如果有python2版本的小伙伴可以去看看它的执行顺序的变化。在3版本上运行我们看到的顺序就是广度优先。

在面试中算问得比较多的一个问题,希望我的解答能带给你帮助。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值