zoukankan      html  css  js  c++  java
  • python多继承(新式类)一

    最近在学习python的多重继承。

    先来了解下多重继承的概念,所谓多重继承,是指python的类可以有两个以上父类,也即有类A,类B,类C,C同时继承类A与类B,此时C中可以使用A与B中的属性与方法。那么问题来了,如果A与B中具有相同名字的方法,这个时候python怎么调用的会是哪个方法呢?

    举个例子:

    class A(object):
      def __init__(self):
       pass

      def foo(self):

        print 'A foo'

    class B(object):
      def __init__(self):
       pass

      def foo(self):

        print 'B foo'

    class C(A,B):

     def __init__(self):

        pass

    testc = C()

    testc.foo()

    实际上打印出来的信息是 A foo,这就说明了调用的是A中的方法。其实在python2.2之后,多继承中基类的寻找顺序是一种广度优先算法,称之为C3的算法(后续博客我会简单介绍下C3算法)。而python2.2之前,使用的是深度优先算法来寻找基类方法。在类C的继承关系中,按照广度优先算法,则会先找到靠近C的基类A,在A中找到foo方法之后,就直接返回了,因此即使后面的基类B中也有foo方法,但是这里不会引用它。

    更加清晰的多继承例子:

    class A(object):
        def foo(self):
            print 'A foo'
            
    class B(object):
        def foo(self):
            print 'B foo'
        def bar(self):
            print 'B bar'
            
    class C1(A,B):
        pass
        
    class C2(A,B):
        def bar(self):
            print 'C2-bar'
            
    class D(C1,C2):
        pass 
        
    
    if __name__ =='__main__':
    print D.__mro__ #只有新式类有__mro__属性,告诉查找顺序是怎样的 d
    =D() d.foo() d.bar()

    执行的结果为:

    (<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)

    A foo (实际上搜索顺序为D=>C1=>A)
    C2 bar(实际上搜索顺序为D=>C1=>C2)

    可以看到,foo找到的是A类中的方法,bar找到的是C2中的方法。

    其实新式类的搜索方法是采用了“广度优先”的方式去查找属性。

    只有新式类有__mro__属性,该属性标记了python继承层次中父类查找的顺序,python多重继承机制中就是按照__mro__的顺序进行查找,一旦找到对应属性,则查找马上返回。

    经过上面的__mro__输出可以发现,D类的继承查找路径为:D=>C1=>C2=>A=>B=>object,通过该查找路径,foo方法将会调用A的foo方法,、bar方法将调用C2的方法,通过实际实验调用,查看输出内容确实与__mro__顺序一样。

     
  • 相关阅读:
    js中级-函数封装
    js中级-11.7
    js中级-11.5
    js中级-11.2
    js中级-this
    js中级-作用域链
    10.23
    10.22
    10.19js
    10.18
  • 原文地址:https://www.cnblogs.com/panyinghua/p/3283726.html
Copyright © 2011-2022 走看看