使用super和类名调用的区别
定义一个父类(A),它有两个子类(C和D),这两个类重写了父类的初始化方法,各自初始化互不相同的属性(C.age;D.sex),E同时继承了这两个子类(C和D),下面分别用类名调用和多继承调用两种方式来实现
多继承使用类名调用
""" 多继承使用类名调用"""
class Animal:
def __init__(self,name):
print("开始调用Animal的init")
self.name=name
print('Animal的init调用结束')
class Dog(Animal):
def __init__(self,name,age):
print('开始调用Dog的初始化方法')
self.age=age
Animal.__init__(self,name)
print('Dog的初始化方法结束调用')
class BigDog(Animal):
def __init__(self,name,sex):
print('开始调用BigDog的初始化方法')
self.sex=sex
Animal.__init__(self,name)
print('BigDog的初始化方法结束调用')
class Hashiqi(Dog,BigDog):
def __init__(self,name,age,sex,character='humorous'):
print('开始调用Hashiqi的初始化方法')
self.character=character
Dog.__init__(self,name,age)
BigDog.__init__(self,name,sex)
print('Hashiqi的初始化方法结束调用')
print(Hashiqi.__mro__)
h=Hashiqi('哮天犬',8,'Boy')
print('姓名:',h.name)
print('年龄:',h.age)
print('性格:',h.character)
执行结果如下:
多继承使用super
""" 多继承使用super"""
class Animal:
def __init__(self,name,*args,**kwargs): # 使用不定长参数打包参数避免多继承报错,
print("开始调用Animal的init")
self.name=name
print('Animal的init调用结束')
class Dog(Animal):
def __init__(self,name,age,*args,**kwargs):
print('开始调用Dog的初始化方法')
self.age=age
super().__init__(name,*args,**kwargs)
print('Dog的初始化方法结束调用')
class BigDog(Animal):
def __init__(self,name,sex,*args,**kwargs):
print('开始调用BigDog的初始化方法')
self.sex=sex
super().__init__(name,*args,**kwargs)
print('BigDog的初始化方法结束调用')
class Hashiqi(Dog,BigDog):
def __init__(self,name,age,sex,character='humorous'):
print('开始调用Hashiqi的初始化方法')
self.character=character
super().__init__(name,age,sex) # 与父类init方法中定义的参数保持一致
print('Hashiqi的初始化方法结束调用')
print(Hashiqi.__mro__)
h=Hashiqi('哮天犬',8,'Boy')
print('姓名:',h.name)
print('年龄:',h.age)
print('性格:',h.character)
执行结果如下:
区别
从执行结果可以看到使用super方法可以使代码更加简洁,并且每个父类只调用了一次,而用类名调用的方式是递归调用的。即使是同一个父类,也会多次调用。
super在单继承和多继承中的区别
单继承中使用super
举一个生动形象的“栗子”:
""" 单继承使用super"""
class Animal:
def __init__(self,name):
print("开始调用Animal的init")
self.name=name
print('Animal的init调用结束')
class Dog(Animal):
def __init__(self,name,age):
print('开始调用Dog的初始化方法')
self.age=age
super().__init__(name) # 与父类init方法中定义的参数保持一致
print('Dog的初始化方法结束调用')
class Hashiqi(Dog):
def __init__(self,name,age,character='humorous'):
print('开始调用Hashiqi的初始化方法')
self.character=character
super().__init__(name,age)
print('Hashiqi的初始化方法结束调用')
h=Hashiqi('哮天犬',8)
print('姓名:',h.name)
print('年龄:',h.age)
print('性格:',h.character)
多继承中使用super
""" 多继承使用super"""
class Animal:
def __init__(self,name,*args,**kwargs): # 使用不定长参数打包参数避免多继承报错,
print("开始调用Animal的init")
self.name=name
print('Animal的init调用结束')
class Dog(Animal):
def __init__(self,name,age,*args,**kwargs):
print('开始调用Dog的初始化方法')
self.age=age
super().__init__(name)
print('Dog的初始化方法结束调用')
class Hashiqi(Dog,Animal):
def __init__(self,name,age,character='humorous',*args,**kwaegs):
print('开始调用Hashiqi的初始化方法')
self.character=character
super().__init__(name,age) # 与父类init方法中定义的参数保持一致
print('Hashiqi的初始化方法结束调用')
print(Hashiqi.__mro__)
h=Hashiqi('哮天犬',8)
print('姓名:',h.name)
print('年龄:',h.age)
print('性格:',h.character)
区别总结
单继承时使用super方法,传入的参数个数需要与父类方法定义的参数保持一致
多继承时使用super方法,可以使用元组或者字典打包参数,防止报错