经典类与新式类的继承顺序

经典类与新式类的继承顺序--两种不同的继承策略。

构造函数(初始化)__init__(self): 的继承策略,就是找哪个__init__(self)的问题

当实例本身有__init__(self) 的时候,会先执行自己的)__init__(self) 函数。

当实例本身没有__init__(self)的时候,它会去找父类中的)__init__(self)函数,此时有2种

继承策略,一种是深度优先,一种是广度优先。

我们看上面的图,先放两句概念上来吓唬吓唬你:

  • 当类是经典类时,多继承情况下,会按照深度优先方式查找
  • 当类是新式类时,多继承情况下,会按照广度优先方式查找

  那么什么是经典类和新式类呢?简而言之,继承自object的类就叫做新式类,object类是python提供的,现在我们还不需要管它从哪里来,因为让类中的很多操作变得更合理了,我们以后记着就这么写就对了。注:下面小伙伴提到,python3.X版本中的类继承默认就是广度优先。

  下面来说广度优先和深度优先,首先,B和C两个类都必须继承自D,A类又继承自B、C,就是针对这种情况,没有为什么。。。背下来!我们对应起来看,这里的基类D就是上例中的classmate,BC就是pythoner和female,A则对应fe_pythoner类。

  经典类中:当我们这样写:fe_pythoner(pythoner,female),对象调用方法的时候,会先在fe_pythoner里面找,然后依次去找pythoner、classmate、最后再找female。如果找到了,就会执行,并且不再继续找下去了。所以我们刚刚在左侧举出得栗子中它先找到了classmate中的drink方法,才打印出了同样的内容。这就是深度优先。

  新式类中:当我们这样写:fe_pythoner(pythoner,female),对象调用方法的时候,会先在fe_pythoner里面找,然后依次去找pythoner、female、最后再找classmate。如果找到了,就会执行,并且不再继续找下去了。所以我们刚刚在右侧举得栗子中它先找到了female、或male中的drink方法,就打印了不同的内容。这就是广度优先。

class classmate(object):
    def __init__(self,name):
        self.name = name

    def eat(self):
        print '%s is eating.'%self.name

    def drink(self):
        print '%s is drinking'%self.name

class female(classmate):

    def drink(self):
        print '%s drink orange juice'%self.name

class male(classmate):

    def drink(self):
        print '%s drink alcohol'%self.name

class pythoner(classmate):

    def occupation(self):
        print '%s is a pythoner.'%self.name



class fe_pythoner(pythoner,female):
    pass
class male_pythoner(pythoner,male):
    pass

eva = fe_pythoner('eva')
eva.drink()

sweet = male_pythoner('sweet')
sweet.drink()

example Code

 如果上面那些你通通没搞清楚,也没关系,在继承的时候可以直接把female类写在前面 fe_pythoner(female,pythoner),这么一来不管怎么样,都是先找female了。

总结:python2的经典类是按照深度优先来继承的,新式类( 包含object字样的) 是按照广度优先来继承的。

           python3 经典类和新式类都是统一按照广度优先来继承的。

 

posted on 2017-07-29 11:33  momo8238  阅读(820)  评论(2编辑  收藏  举报