美文网首页
调用父类中的方法

调用父类中的方法

作者: import_hello | 来源:发表于2018-09-12 07:11 被阅读0次

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

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

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

      <parent class name>.<method name>(self, <other arguments>)
      
    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) 。

    相关文章

      网友评论

          本文标题:调用父类中的方法

          本文链接:https://www.haomeiwen.com/subject/knygbftx.html