zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    React的一些原则
    CSS/H5保留显示 textarea输入的空格和换行
    一种css效果:标题带色块,React+Less
    Taro,实现小程序在样式文件中导入背景图片
    JS合并两个函数
    bootstrap-table使用stickyHeader固定表头时,表头不跟随表体水平滚动问题解决
    二次封装bootstrap-table及功能优化
    iframe在ios上不能滚动问题解决
    移动端滚动不流畅问题
    Error: Chromium revision is not downloaded. Failed to download Chromium
  • 原文地址:https://www.cnblogs.com/fcyworld/p/6240482.html
Copyright © 2011-2022 走看看