python 多继承

读django类视图代码时,遇到这样一个问题:

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

    def get_data(self, **kwargs):
        print "enter A"
        if "A" not in kwargs:
            kwargs['A'] = "value A"
        print "leave A"
        return kwargs


class B(A):
    def get_data(self, **kwargs):
        print "enter B"
        if "B" not in kwargs:
            kwargs['B'] = "value B"
        print "leave B"
        return super(B, self).get_data(**kwargs)


class C(A):
    def get_data(self, **kwargs):
        print "enter C"
        if "C" not in kwargs:
            kwargs['C'] = "value C"
        print "leave C"
        return super(C, self).get_data(**kwargs)


class D(C, B):
    def use_data(self):
        print "enter D"
        data = self.get_data(D="value D")
        print "data value:",data
        print "leave D"
        return

if __name__ =="__main__":
    d = D()
    d.use_data()

这套程序中,D的use_data函数中的data的值应该是什么,这里的运行结果是:

enter D
enter C
leave C
enter B
leave B
enter A
leave A
data value: {'A': 'value A', 'C': 'value C', 'B': 'value B', 'D': 'value D'}
leave D

需要注意的是:这里的A必须继承object,如果A不继承object,程序变成这样:

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

    def get_data(self, **kwargs):
        print "enter A"
        if "A" not in kwargs:
            kwargs['A'] = "value A"
        print "leave A"
        return kwargs


class B(A):
    def get_data(self, **kwargs):
        print "enter B"
        if "B" not in kwargs:
            kwargs['B'] = "value B"
        print "leave B"
        return super(B, self).get_data(**kwargs)


class C(A):
    def get_data(self, **kwargs):
        print "enter C"
        if "C" not in kwargs:
            kwargs['C'] = "value C"
        print "leave C"
        return super(C, self).get_data(**kwargs)


class D(C, B):
    def use_data(self):
        print "enter D"
        data = self.get_data(D="value D")
        print "data value:", data
        print "leave D"
        return

if __name__ =="__main__":
    d = D()
    d.use_data()

运行结果会报错:

/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/apple/mygit/kd/demo/class_inheritance_example.py
Traceback (most recent call last):
enter D
  File "/Users/apple/mygit/kd/demo/class_inheritance_example.py", line 41, in <module>
enter C
    d.use_data()
leave C
  File "/Users/apple/mygit/kd/demo/class_inheritance_example.py", line 34, in use_data
    data = self.get_data(D="value D")
  File "/Users/apple/mygit/kd/demo/class_inheritance_example.py", line 28, in get_data
    return super(C, self).get_data(**kwargs)
TypeError: must be type, not classobj

这是python继承问题,通过问度娘,找到好多文章,这里按自己的方式记录整理,以备后续使用。

python实现继承的方法

python可以采用两种方法实现继承。

方法1:使用父类名,例:

 class A:
  def __init__(self):
   print "enter A"
   print "leave A"

 class B(A):
  def __init__(self):
   print "enter B"
   A.__init__(self)
   print "leave B"

方法2,使用super,例:

 class A:
  def __init__(self):
   print "enter A"
   print "leave A"

 class B(A):
  def __init__(self):
   print "enter B"
   super(C,self).__init__()
   print "leave B"

方法1是python2.2之前的版本实现继承采用的方法。该方法的问题在于如果有多个继承,当父类更改名字时,所有的子类都要进行相应修改。因此,python2.2之后的版本使用方法2实现继承。

super

super是MRO中的一个类。MRO全称Method Resolution Order,代表类的继承顺序。

关于super,需要注意的一点是它是一个访问排序器,而不是父类。

计划2017年8月底之前翻译完成对super讲解最透彻的一篇文章是Raymond Hettinger的一篇文章https://rhettinger.wordpress….

    原文作者:李俊
    原文地址: https://segmentfault.com/a/1190000010612206
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞