多继承以及mro顺序

  • 多继承时,相对于使用类名.init()方法,要把每个父类全部写一遍
  • 而super只用一句话,执行了全部父类的方法,这也是为何继承需要全部传参的原因
  • 并且使用super方法继承多个父类,调用父类的同名方法是根据mro顺序进行获取,默认一般调用第一个父类的属性和方法
class Parent(object):
    def __init__(self, name, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        print('parent的init开始被调用')
        self.name = name
        print('parent的init结束被调用')

class Son1(Parent):
    def __init__(self, name, age, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son1的init开始被调用')
        self.age = age
        super().__init__(name, *args, **kwargs)  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son1的init结束被调用')

class Son2(Parent):
    def __init__(self, name, gender, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son2的init开始被调用')
        self.gender = gender
        super().__init__(name, *args, **kwargs)  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son2的init结束被调用')

总结: 1.super().__init__相对于类名.init,在单继承上用法基本无差

2.但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,但用类名.方法 会被执行多次

3.多继承时,使用super方法,对父类的传参数,是由于python中的super的算法导致的原因,必须把参数全部传递,否则会报错 4.单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数 5.多继承时,相对于使用类名.__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

  • 中间表示任何它的子类重写了该值,都不会影响其他子类和他的父类,仅仅是在此子类中被改变

  • 最后表示如果该值在父类中被改变,这个改变会影响,未重写子类的值,重写的子类则不会影响

  • mro顺序表按c3算法得到

  • slef记录实例空间的地址

  • 类里面不知道实例对象的空间地址,无法访问实例对象中的实例属性

  • 构造函数

  • 1、创建对象

  • 2、初始化属性

猜你喜欢

转载自blog.csdn.net/s201314yh/article/details/80025173