Python类中的super方法在多继承中的用法(一个例子看懂super()的使用方法)

Python类中如何调用父类?

  1. 直接写父类的名字
  2. 使用不带参数的super()方法
  3. 使用带参数的super(父类)方法

第1种方法比较简单,直接在调用的时候指定父类名称即可。但是这种直接使用的方式会有一个副作用,当存在多重继承的时候,父类的初始化方法会被多次调用。解决方法就是使用不带参数的super方法,该方法会使用一个D3算法,该算法会确保所有类的初始化方法仅仅调用一次。看例子:

class Parent(object):
    def __init__(self, name, *args, **kwargs):
        print("init Parent begin")
        self.name = name
        print("init Parent End")


class Son1(Parent):
    def __init__(self, name, gender, *args, **kwargs):
        print("init Son1 begin")
        self.gender = gender
        super().__init__(name, *args, **kwargs)
        print("init Son1 End")

class Son2(Parent):
    def __init__(self, name, age, *args, **kwargs):
        print("init Son2 begin")
        self.age = age
        super().__init__(name, *args, **kwargs)
        print("init Son2 End")

class Grandson(Son1, Son2):
    def __init__(self, name, gender, age):
        print("init Grandson begin")
        super().__init__(name, gender, age)
        print("init Grandson End")

print(Grandson.mro())

grandson = Grandson("zhangsan", "M", 23)
print("name = %s"%grandson .name)
print("gender = %s"%grandson .gender)
print("age = %s"%grandson .name)

输出结果如下:
[<class ‘main.Grandson’>, <class ‘main.Son1’>, <class ‘main.Son2’>, <class ‘main.Parent’>, <class ‘object’>]
上面的输出就是Grandson.mro()打印出来的对于多重继承调用super()时所采用的顺序,从下面的输出也可以跟上面进行对照,首先调用Grandson的初始化,然后调用Son1的初始化,再调用Son2的初始化,最后调用Parent的初始化。
init Grandson begin
init Son1 begin
init Son2 begin
init Parent begin
init Parent End
init Son2 End
init Son1 End
init Grandson End

如果把super都换成每个类的父类名,那么就可以得到下面的结果. 测试代码和结果如下,可以看到Parent被调用多次:

class Parent(object):
    def __init__(self, name, *args, **kwargs):
        print("init Parent begin")
        self.name = name
        print("init Parent End")


class Son1(Parent):
    def __init__(self, name, gender, *args, **kwargs):
        print("init Son1 begin")
        self.gender = gender
        super().__init__(name, *args, **kwargs)
        print("init Son1 End")

class Son2(Parent):
    def __init__(self, name, age, *args, **kwargs):
        print("init Son2 begin")
        self.age = age
        super().__init__(name, *args, **kwargs)
        print("init Son2 End")

class Grandson(Son1, Son2):
    def __init__(self, name, gender, age):
        print("init Grandson begin")
        super().__init__(name, gender, age)
        print("init Grandson End")

print(Grandson.mro())

grandson = Grandson("zhangsan", "M", 23)
print("name = %s"%grandson.name)
print("gender = %s"%grandson.gender)
print("age = %s"%grandson.age)

输出结果如下:
[<class ‘main.Grandson’>, <class ‘main.Son1’>, <class ‘main.Son2’>, <class ‘main.Parent’>, <class ‘object’>]
init Grandson begin
init Son1 begin
init Parent begin
init Parent End

init Son1 End
init Son2 begin
init Parent begin
init Parent End

init Son2 End
init Grandson End
name = zhangsan
gender = M
age = 23

如果继承的再多一些,Parent将被调用更多次,这是难以接受的,所以应该尽量使用super方法。

顺便说一句,supe()如果指定参数的话,会直接调用指定参数类的方法。将会打破MRO指定的默认顺序,跳转到对应类上去执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值