调用父类中的方法

转载须注明出处:@Orca_J35
可参考另外两则笔记:方法解析顺序(MRO) | super()

子类中的方法会覆盖父类中的同名方法,如果需要调用父类中的方法,可以采用以下两种方式:

  1. 通过父类名称来调用父类中方法:

    .(self, )
    
  2. 构造一个 super 对象,并通过该对象调用父类中的方法。这种方法的优点在于无需显式引用父类,从而使代码更容易维护;并且在"钻石形"多继承的类层次结构中可避免重复调用父类中的方法。

在单继承的类层次结构中,上述两种方法并没有太显著的区别。super 的优点在于无需显式引用父类,从而使代码更容易维护。比如,在子类中调用父类的 __init__() 方法,以确保正确初始化:

class Base:
    def __init__(self, arg):
        print('Base.__init__')

class A(Base):
    def __init__(self, arg):
        Base.__init__(self, arg) # 等效于 super().__init__(arg)
        print('A.__init__')

在"钻石形"多继承的类层次结构中,如果直接引用父类名称,则可能会重复调用父类中的方法。比如,考虑如下的情况:

class Base:
    def __init__(self):
        print('Base.__init__')

class A(Base):
    def __init__(self):
        Base.__init__(self)
        print('A.__init__')

class B(Base):
    def __init__(self):
        Base.__init__(self)
        print('B.__init__')

class C(A,B):
    def __init__(self):
        A.__init__(self)
        B.__init__(self)
        print('C.__init__')

如果你运行这段代码就会发现 Base.__init__() 被调用两次,如下所示:

>>> c = C()
Base.__init__
A.__init__
Base.__init__
B.__init__
C.__init__
>>>

两次调用 Base.__init__() 通常没有什么坏处,但有时却会出现意外。如果我们在代码中使用 super(),则可避免重复调用的问题:

class Base:
    def __init__(self):
        print('Base.__init__')

class A(Base):
    def __init__(self):
        super().__init__()
        print('A.__init__')

class B(Base):
    def __init__(self):
        super().__init__()
        print('B.__init__')

class C(A,B):
    def __init__(self):
        super().__init__()  # Only one call to super() here
        print('C.__init__')

运行这个新版本后,你会发现每个 __init__() 方法只会被调用一次了:

>>> c = C()
Base.__init__
B.__init__
A.__init__
C.__init__
>>>

为了弄清 super() 的原理,这里需要补充一个知识点:方法解析顺序(MRO) 。

你可能感兴趣的:(调用父类中的方法)