Python使用super初始化超类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python使用super初始化超类相关的知识,希望对你有一定的参考价值。
初始化超类的传统方式,在子类的实例中调用超类的__init__()方法。
但是传统的方法有两个问题,比如:
问题1:
1 class MyBaseClass: 2 def __init__(self, value): 3 self.value = value 4 5 6 class TimesTwo: 7 def __init__(self): 8 self.value *= 2 9 10 11 class PlusFive: 12 def __init__(self): 13 self.value += 5 14 15 16 class OneWay(MyBaseClass, TimesTwo, PlusFive): 17 def __init__(self,value): 18 MyBaseClass.__init__(self, value) 19 TimesTwo.__init__(self) 20 PlusFive.__init__(self) 21 22 23 class AnotherWay(MyBaseClass, PlusFive, TimesTwo): 24 def __init__(self,value): 25 MyBaseClass.__init__(self, value) 26 TimesTwo.__init__(self) 27 PlusFive.__init__(self) 28 29 foo = OneWay(5) 30 print(‘OneWay (5*2)+5=‘, foo.value) 31 foo = AnotherWay(5) 32 print(‘AnotherWay:‘, foo.value)
结果为:
从结果可以看出,即使改变了子类的继承顺序,调用的顺序并没有改变。
问题2:
如果子类继承自两个单独的超类,而那两个超类又继承自同一个公共基类,那么就构成了钻石型继承。
这种继承会使钻石顶端的公共基类多次执行__init__()方法,从而产生意外。
比如:
1 class MyBaseClass: 2 def __init__(self, value): 3 self.value = value 4 5 6 class TimesFive(MyBaseClass): 7 def __init__(self, value): 8 MyBaseClass.__init__(self, value) 9 self.value *= 2 10 11 12 class PlusTwo(MyBaseClass): 13 def __init__(self, value): 14 MyBaseClass.__init__(self, value) 15 self.value += 2 16 17 18 class ThisWay(TimesFive, PlusTwo): 19 def __init__(self, value): 20 TimesFive.__init__(self, value) 21 PlusTwo.__init__(self, value) 22 23 24 25 foo = ThisWay(5) 26 print(‘Should be (5*5)+2 but is ‘, foo.value)
在调用PlusTwo.__init__()时候,又一次调用MyBaseClass.__init__()又一次把value变为5
以上两种问题都可以使用super解决,方法解析顺序mro(method resolution order),以标准的流程安排超类之间的初始化顺序。
比如这次用super初始化超类
1 class MyBaseClass: 2 def __init__(self, value): 3 self.value = value 4 5 6 class TimesFive(MyBaseClass): 7 def __init__(self, value): 8 super(TimesFive, self).__init__(value) 9 self.value *= 5 10 11 12 class PlusTwo(MyBaseClass): 13 def __init__(self, value): 14 super(PlusTwo, self).__init__(value) 15 self.value += 2 16 17 18 class GoodWay(TimesFive, PlusTwo): 19 def __init__(self, value): 20 super(GoodWay, self).__init__(value) 21 22 23 foo = GoodWay(5) 24 print(‘Should be 5*(5+2) and is ‘, foo.value)
并且可以使用
print(GoodWay.mro())
来查看初始化顺序:
参考资料:Effective Python
以上是关于Python使用super初始化超类的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 中,为啥为没有定义超类的类调用 super() 函数不是错误? [复制]