本文實(shí)例講述了Python高級(jí)編程之繼承問(wèn)題。分享給大家供大家參考,具體如下:
多繼承問(wèn)題
1.單獨(dú)調(diào)用父類:
一個(gè)子類同時(shí)繼承自多個(gè)父類,又稱菱形繼承、鉆石繼承。
使用父類名.init(self)方式調(diào)用父類時(shí):
例:
class Parent(object): def __init__(self, name): self.name = name print('parent的init結(jié)束被調(diào)用')class Son1(Parent): def __init__(self, name, age): Parent.__init__(self, name) self.age = age print('Son1的init結(jié)束被調(diào)用')class Son2(Parent): def __init__(self, name, gender): Parent.__init__(self, name) self.gender = gender print('Son2的init結(jié)束被調(diào)用')class Grandson(Son1, Son2): def __init__(self, name, age, gender): Son1.__init__(self, name, age) # 單獨(dú)調(diào)用父類的初始化方法 Son2.__init__(self, name, gender) print('Grandson的init結(jié)束被調(diào)用')gs = Grandson('grandson', 12, '男')
執(zhí)行結(jié)果:
可以看出使用父類名.init(self)方式調(diào)用父類時(shí),parent父類被調(diào)用了兩次,此方法對(duì)于多繼承不太合適。
2.MRO順序:
上述代碼,我們發(fā)現(xiàn)由于多繼承情況,parent類被的屬性被構(gòu)造了兩次,如果在更加復(fù)雜的結(jié)構(gòu)下可能更加嚴(yán)重。
為了解決這個(gè)問(wèn)題,Python官方采用了一個(gè)算法將復(fù)雜結(jié)構(gòu)上所有的類全部都映射到一個(gè)線性順序上,而根據(jù)這個(gè)順序就能夠保證所有的類都會(huì)被構(gòu)造一次。
這個(gè)順序就是MRO順序。
MRO順序采用C3算法廣度優(yōu)先遍歷。
使用方法: 類名.mro()或類名.mro()
3.super調(diào)用父類:
使用super().init()方式調(diào)用父類時(shí):
例:
class Parent(object): def __init__(self, name, *args, **kwargs): # 為避免多繼承報(bào)錯(cuò),使用不定長(zhǎng)參數(shù),接受參數(shù) self.name = name print('parent的init結(jié)束被調(diào)用')class Son1(Parent): def __init__(self, name, age, *args, **kwargs): # 為避免多繼承報(bào)錯(cuò),使用不定長(zhǎng)參數(shù),接受參數(shù) self.age = age super().__init__(name, *args, **kwargs) # 為避免多繼承報(bào)錯(cuò),使用不定長(zhǎng)參數(shù),接受參數(shù) print('Son1的init結(jié)束被調(diào)用')class Son2(Parent): def __init__(self, name, gender, *args, **kwargs): # 為避免多繼承報(bào)錯(cuò),使用不定長(zhǎng)參數(shù),接受參數(shù) self.gender = gender super().__init__(name, *args, **kwargs) # 為避免多繼承報(bào)錯(cuò),使用不定長(zhǎng)參數(shù),接受參數(shù) print('Son2的init結(jié)束被調(diào)用')class Grandson(Son1, Son2): def __init__(self, name, age, gender): # 多繼承時(shí),相對(duì)于使用類名.__init__方法,要把每個(gè)父類全部寫(xiě)一遍 # 而super只用一句話,執(zhí)行了全部父類的方法,這也是為何多繼承需要全部傳參的一個(gè)原因 # super(Grandson, self).__init__(name, age, gender) super().__init__(name, age, gender) print('Grandson的init結(jié)束被調(diào)用')gs = Grandson('grandson', 12, '男')print(Grandson.__mro__)
運(yùn)行結(jié)果:
parent父類只被調(diào)用了一次,super方法會(huì)按照MRO順序調(diào)用下一個(gè)父類。
總結(jié):
(1)MRO保證了多繼承情況 每個(gè)類只出現(xiàn)一次
新聞熱點(diǎn)
疑難解答
圖片精選