在使用Python編寫(xiě)面向?qū)ο蟮拇a時(shí),我們會(huì)常常使用“繼承”這種開(kāi)發(fā)方式。例如下面這一段代碼:
class Info: def __init__(self): pass def calc_age(self): print('我是父類(lèi)的方法') class PeopleInfo(Info): def __init__(self): super().__init__() def calc_age(self): print(123456)
如果你使用 PeopleInfo 初始化一個(gè)對(duì)象,然后調(diào)用這個(gè)類(lèi)的 calc_age 方法,我們來(lái)看看運(yùn)行效果,如下圖所示:
可以看出,父類(lèi) Info 里面的 calc_age 被子類(lèi)里面的 calc_age 給“覆蓋”了。
到目前為止,應(yīng)該都是你已經(jīng)知道的東西。那么下一個(gè)問(wèn)題,請(qǐng)問(wèn) PeopleInfo 里面的 __init__ 會(huì)不會(huì)覆蓋 Info 里面的 __init__ ?
為了確認(rèn)這一點(diǎn),我們來(lái)測(cè)試一下:
class Info: def __init__(self): print('我是父類(lèi)的__init__') def calc_age(self): print('我是父類(lèi)的方法') class PeopleInfo(Info): def __init__(self): super().__init__() print('我是之類(lèi)的初始化方法') def calc_age(self): print(123456)
運(yùn)行效果如下圖所示:
這里你發(fā)現(xiàn)父類(lèi)和子類(lèi)的 __init__ 都被運(yùn)行了。
不過(guò)你可能會(huì)強(qiáng)行解釋為:在子類(lèi)的 __init__ 里面,有一行 super().__init__() ,這個(gè)地方可能子類(lèi)還沒(méi)有完全覆蓋父類(lèi),所以先運(yùn)行了父類(lèi)的方法。等到子類(lèi)的 __init__ 全部執(zhí)行完成以后,才會(huì)覆蓋父類(lèi)。
當(dāng)然,這種強(qiáng)行詭辯顯然是錯(cuò)誤的,但為了證明這里你看到的現(xiàn)象和這個(gè) super().__init__() 沒(méi)有任何關(guān)系,我們不使用 __init__ ,而是自己定義一個(gè):
class Info: def __init__(self): pass def __calc_age(self): print('我是父類(lèi)的方法') def run_father(self): self.__calc_age() class PeopleInfo(Info): def __init__(self): super().__init__() pass def __calc_age(self): print(123456) def run_son(self): self.__calc_age()
運(yùn)行效果如下圖所示:
從這里可以看出,父類(lèi)和子類(lèi)的 __calc_age 都成功運(yùn)行了。
這是因?yàn)椋赑ython里面,類(lèi)方法或者屬性如果以雙下劃線開(kāi)頭,那么他們就是類(lèi)的私有方法,在被繼承的時(shí)候,即使子類(lèi)有相同名字的以雙下劃線開(kāi)頭的屬性或者方法也不會(huì)覆蓋父類(lèi)。
而且這些以雙下劃線開(kāi)頭的私有方法或者屬性,在類(lèi)內(nèi)部可以自由被其他方法調(diào)用,但是在實(shí)例對(duì)象里面是不能直接調(diào)用的,如下圖所示:
那么Python是如何實(shí)現(xiàn)這一點(diǎn)的呢?實(shí)際上Python僅僅是改了一個(gè)名字而已。我們使用 dir 函數(shù)看看實(shí)例對(duì)象 kingname 里面有哪些內(nèi)容,如下圖所示:
大家請(qǐng)注意方框框住的內(nèi)容,其中的 _Info__calc_age 就是父類(lèi)中的 __calc_age ,而 _PeopleInfo__calc_age 就是子類(lèi)中的 __calc_age 。Python僅僅是改了一個(gè)名字,在這種雙下劃線的私有方法或者私有屬性的前面加上了 _類(lèi)名 ,這樣就確保了子類(lèi)和父類(lèi)的方法名不一致。
所以,雖然 在規(guī)范上,這種雙下劃線的私有方法和私有屬性是不應(yīng)該在外部訪問(wèn)的 ,但是如果你想強(qiáng)行訪問(wèn),可以個(gè)使用這種改名以后的名字:
kingname = PeopleInfo() kingname._PeopleInfo__calc_age() # 強(qiáng)行調(diào)用子類(lèi)的私有方法 kingname._Info__calc_age() # 強(qiáng)行調(diào)用父類(lèi)的私有方法
運(yùn)行效果如下圖所示:
總結(jié)
以上所述是小編給大家介紹的Python中使用雙下劃線防止類(lèi)屬性被覆蓋問(wèn)題,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
