1. 程式人生 > >Python 在子類中呼叫父類方法詳解(單繼承、多層繼承、多重繼承)

Python 在子類中呼叫父類方法詳解(單繼承、多層繼承、多重繼承)

測試環境:

win7 64位

Python版本:Python 3.3.5

程式碼實踐:

1、在子類中通過“類名”呼叫父類的方法

class FatherA:

    def __init__(self):

        print('init action in father class A')



class SubClassB(FatherA):

    def __init__(self):

        print('init action in subclass B')

        FatherA.__init__(self) # 在子類中呼叫父類的方法:父類名.方法名稱(引數)
if __name__ == '__main__': b = SubClassB()

執行結果:

>>>

init action in subclass B

init action in father class A

缺點:當一個子類的父類發生變化時(如類SubClassB的父類由FatherA變為FatherD時),必須遍歷整個類定義,把子類中所有的父類類名全部替換過來

2、在子類中通過“super”方法呼叫父類的方法

場景1、單層繼承

class FatherA:

    def __init__(self):

        print('init action in father class A'
) class SubClassB(FatherA): def __init__(self): print('init action in father class B') super().__init__() # 在子類中呼叫父類的方法:super().方法名稱(引數) if __name__ == '__main__': b = SubClassB() class FatherA: def __init__(self): print('init action in father class A'
) class SubClassB(FatherA): def __init__(self): print('init action in subclass B') super(SubClassB, self).__init__() # 在子類中呼叫父類的方法:super(type, obj).方法名稱(引數) if __name__ == '__main__': b = SubClassB()

執行結果:

>>>

init action in father class B

init action in father class A

說明:

1、super(type, obj),其中obj必須是type型別、type子類型別的例項,否則會報錯:

TypeError: super(type, obj): obj must be an instance or subtype of type

2、super().init() 效果等同 super(SubClassB, self). init()

場景2、多層繼承

實驗1:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class SubClassB(FatherA):

    def __init__(self):

        print('init action in subclass B')

        super().__init__()



class SubClassC(SubClassB):

    def __init__(self):

        print('init action in subclass C')

        super().__init__()



if __name__ == '__main__':

    b = SubClassC()

執行結果:

>>>

init action in subclass C

init action in subclass B

init action in father class A

對比實驗1-1:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class SubClassB(FatherA):

    def __init__(self):

        print('init action in subclass B')

        super().__init__()



class SubClassC(SubClassB):

    def __init__(self):

        print('init action in subclass C')

        super(SubClassB, self).__init__()





if __name__ == '__main__':

    b = SubClassC()

執行結果:


>>>

init action in subclass C

init action in father class A

>>> 

對比實驗1-2:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class SubClassB(FatherA):

    def __init__(self):

        print('init action in subclass B')

        super().__init__()



class SubClassC(SubClassB):

    def __init__(self):

        print('init action in subclass C')

        super(FatherA, FatherA).__init__(self) # 在子類中呼叫父類的方法:super(type, type).方法名稱(引數)





if __name__ == '__main__':

    b = SubClassC()

說明:可把 super(FatherA, FatherA).init(self) 換成:

super(FatherA, self).init()

super(FatherA, SubClassB).init(self)

super(FatherA, SubClassC).init(self)

注意:以上這種情況,必須給init傳遞引數self,否則會報錯:

TypeError: init() missing 1 required positional argument: ‘self’

執行結果:

>>>

init action in subclass C

>>> 

說明:super(type1, type2) ,type2必須和type1相同型別,或者其子類型別

實驗2:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class SubClassB(FatherA):

    def __init__(self):

        print('init action in subclass B')

        super().__init__()



class SubClassC(SubClassB):

    def __init__(self):

        print('init action in subclass C')

        super().__init__()



class SubClassD(SubClassC):

    def __init__(self):

        print('init action in subclass D')

        super().__init__()



if __name__ == '__main__':

    b = SubClassD()

執行結果:


>>>

init action in subclass D

init action in subclass C

init action in subclass B

init action in father class A

對比實驗2-1:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class SubClassB(FatherA):

    def __init__(self):

        print('init action in subclass B')

        super().__init__()



class SubClassC(SubClassB):

    def __init__(self):

        print('init action in subclass C')

        super().__init__()



class SubClassD(SubClassC):

    def __init__(self):

        print('init action in subclass D')

        super(SubClassB, self).__init__()



if __name__ == '__main__':

    b = SubClassD()

執行結果:


>>>

init action in subclass D

init action in father class A

>>> 

對比實驗2-2:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class SubClassB(FatherA):

    def __init__(self):

        print('init action in subclass B')

        super().__init__()



class SubClassC(SubClassB):

    def __init__(self):

        print('init action in subclass C')

        super().__init__()



class SubClassD(SubClassC):

    def __init__(self):

        print('init action in subclass D')

        super(SubClassC, self).__init__()



if __name__ == '__main__':

    b = SubClassD()

執行結果:


>>>

init action in subclass D

init action in subclass B

init action in father class A

通過對比實驗2-1, 2-2,可看出super(type[,type2_or_obj]),type決定了super呼叫方法所在的父類–type的父類(如果有的話),即type決定了前往哪個父類呼叫指定的方法

場景3、多重繼承

實驗1:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class FatherB:

    def __init__(self):

        print('init action in father class B')



class SubClassC(FatherA, FatherB):

    def __init__(self):

        print('init action in subclass C')

        super(FatherB).__init__()





if __name__ == '__main__':

    b = SubClassC()

執行結果:


>>>

init action in subclass C

對比實驗1-1:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class FatherB:

    def __init__(self):

        print('init action in father class B')



class SubClassC(FatherB, FatherA):

    def __init__(self):

        print('init action in subclass C')

        super().__init__()



if __name__ == '__main__':

    b = SubClassC()

執行結果:


>>>

init action in subclass C

init action in father class B

>>> 

對比實驗1-2:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class FatherB:

    def __init__(self):

        print('init action in father class B')



class SubClassC(FatherA, FatherB):

    def __init__(self):

        print('init action in subclass C')

        super().__init__()



if __name__ == '__main__':

    b = SubClassC()

執行結果:


>>>

init action in subclass C

init action in father class A

>>> 

對比實驗1-3:

class FatherA:

    def __init__(self):

        print('init action in father class A')



class FatherB:

    def __init__(self):

        print('init action in father class B')



class SubClassC(FatherA, FatherB):

    def __init__(self):

        print('init action in subclass C')

        super(FatherB).__init__()



if __name__ == '__main__':

    b = SubClassC()
>>> ================================ RESTART ================================

>>>

init action in subclass C

對比實驗1-4:

class FatherA:

    def __init__(self):

        print('init action in father class A')



    def testfn(self, arg):

        print('testfn in father class A')



class FatherB:

    def __init__(self):

        print('init action in father class B')



    def testfn(self):

        print('testfn in father class B')



class SubClassC(FatherA, FatherB):

    def __init__(self):

        print('init action in subclass C')

        super().testfn()



if __name__ == '__main__':

    b = SubClassC()

執行結果:


>>>

init action in subclass C

Traceback (most recent call last):

  File "C:/Users/Administrator/Desktop/1.py", line 21, in

    b = SubClassC()

  File "C:/Users/Administrator/Desktop/1.py", line 18, in __init__

    super().testfn()

TypeError: testfn() missing 1 required positional argument: 'arg'

>>> 

對比實驗1-5:

class FatherA:

    def __init__(self):

        print('init action in father class A')



    def testfn(self):

        print('testfn in father class A')



class FatherB:

    def __init__(self):

        print('init action in father class B')



    def testfn(self, arg):

        print('testfn in father class B')



class SubClassC(FatherA, FatherB):

    def __init__(self):

        print('init action in subclass C')

        super().testfn()



if __name__ == '__main__':

    b = SubClassC()

執行結果:


>>>

init action in subclass C

testfn in father class A

說明:通過對比實驗1-1,1-2,1-3,1-4,1-5可以看出,子類水平方向上,繼承多個父類,以super().method(引數)方法呼叫父類的方法,如果不同父類中存在同名方法method(不管引數列表是否相同),則按繼承順序,選擇第一個父類中的方法。,如果想要呼叫多個方法咋辦?如下,通過類名呼叫

class FatherA:

    def __init__(self):

        print('init action in father class A')



class FatherB:

    def __init__(self):

        print('init action in father class B')



class SubClassC(FatherA, FatherB):

    def __init__(self):

        print('init action in subclass C')

        FatherA.__init__(self)

        FatherB.__init__(self)



if __name__ == '__main__':

    b = SubClassC()

>>>

init action in subclass C

init action in father class A

init action in father class B

>>>