1. 程式人生 > >python類中super()用法

python類中super()用法

Note: super() only works for new-style classes.


super() 函式的一個常見用法是在 __init__() 方法中確保父類被正確的初始化了

作用

super() 函式是子類用於呼叫父類(超類)的一個方法。

super 是用來解決多重繼承問題的,直接用類名呼叫父類(Base.__init__(self))方法在使用單繼承的時候沒問題,但是如果使用多繼承,會涉及到查詢順序(MRO)、重複呼叫(鑽石繼承)等種種問題。

MRO 就是類的方法解析順序表, 其實也就是繼承父類方法時的順序表。

使用場景

假如說在父類中實現了一個方法,你想在子類中使用父類的這個方法並且做一定擴充套件但是又不想完全重寫,並且這個場景中的繼承屬於多繼承,那麼super()就出場了,可以實現方法的增量修改。

呼叫方式

python2:

    super(CurrentClass, self).method(arg)

python3:

    super().method(arg)

使用舉例

class BasicClassPeople(object):
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def short_introduction(self):
        print
'My name is {}, a {}, this year I am {} years old'.format(self.name,self.gender,self.age) class ExtenClassOne(BasicClassPeople): def __init__(self,name,age,gender,job): super(ExtenClassOne, self).__init__(name,gender,age) self.job = job def short_introduction(self): print
'My name is {}, a {}, this year I am {} years old, my job is {}'.format(self.name, self.gender, self.age,self.job)

在上邊的程式中ExtenClassOne繼承自BasicClassPeople,但是它想在初始化的時候為類新增加一個屬性,如果不使用super的話我們就只能重寫初始化函數了,但是使用了super之後我們只需要在定義擴充套件的初始化函式時呼叫父類初始化函式,然後把自己新增的屬性新增到呼叫語句後面就可以了。

super()可以避免重複呼叫

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__
>>>

使用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__
>>>