Python中新式類與經(jīng)典類的區(qū)別詳析
1.新式類與經(jīng)典類
在Python 2及以前的版本中,由任意內(nèi)置類型派生出的類(只要一個內(nèi)置類型位于類樹的某個位置),都屬于“新式類”,都會獲得所有“新式類”的特性;反之,即不由任意內(nèi)置類型派生出的類,則稱之為“經(jīng)典類”。
“新式類”和“經(jīng)典類”的區(qū)分在Python 3之后就已經(jīng)不存在,在Python 3.x之后的版本,因?yàn)樗械念惗寂缮詢?nèi)置類型object(即使沒有顯示的繼承object類型),即所有的類都是“新式類”。
官方文檔 https://www.python.org/doc/newstyle/
2.繼承順序的區(qū)別
主要是在多重繼承時才會遇到這個問題。
經(jīng)典類的鉆石繼承是深度優(yōu)先,即從下往上搜索;新式類的繼承順序是采用C3算法(非廣度優(yōu)先)。
對經(jīng)典類進(jìn)行代碼驗(yàn)證(所有經(jīng)典類的代碼必須在Python2下運(yùn)行,下同),ClassicClassB 繼承自 ClassicClassA,SubClassicClass繼承自ClassicClassB,ClassicClassC:
class ClassicClassA(): var = 'Classic Class A' class ClassicClassB(ClassicClassA): pass class ClassicClassC(): var = 'Classic Class C' class SubClassicClass(ClassicClassB, ClassicClassC): pass if __name__ == '__main__': print(SubClassicClass.var)
在SubClassicClass對var屬性進(jìn)行搜索的過程中,根據(jù)從下到上的原則,會優(yōu)先搜索ClassicClassB,而ClassicClassB沒有var屬性,會繼續(xù)往上搜索ClassicClassB的超類ClassicClassA,在ClassicClassA中發(fā)現(xiàn)var屬性后停止搜索,var的值為ClassicClassA中var的值;而ClassicClassC的var屬性從始至終都未被搜索到。
從運(yùn)行結(jié)果可以看出,輸出的是Classic Class A,可見類繼承的搜索是深度優(yōu)先,由下至上進(jìn)行搜索。
Classic Class A
新式類的繼承順序并非是廣度優(yōu)先,而是C3算法,只是在部分情況下,C3算法的結(jié)果恰巧與廣度優(yōu)先的結(jié)果相同。
對新式類的繼承搜索順序進(jìn)行代碼驗(yàn)證,新式類中,可以使用mro函數(shù)來查看類的搜索順序(這也算是一個區(qū)別),如SubNewStyleClass.mro()。
class NewStyleClassA(object): var = 'New Style Class A' class NewStyleClassB(NewStyleClassA): pass class NewStyleClassC(NewStyleClassA): var = 'New Style Class C' class SubNewStyleClass(NewStyleClassB, NewStyleClassC): pass if __name__ == '__main__': print(SubNewStyleClass.mro()) print(SubNewStyleClass.var)
從代碼運(yùn)行結(jié)果看,恰巧與從左至右的廣度優(yōu)先預(yù)期結(jié)果相同。
[<class '__main__.SubNewStyleClass'>, <class '__main__.NewStyleClassB'>, <class '__main__.NewStyleClassC'>, <class '__main__.NewStyleClassA'>, <type 'object'>]
New Style Class C
但是不代表新式類的繼承順序就是廣度優(yōu)先,可以稍微修改下代碼進(jìn)行驗(yàn)證:NewStyleClassC改為繼承自object
class NewStyleClassA(object): var = 'New Style Class A' class NewStyleClassB(NewStyleClassA): pass class NewStyleClassC(object): var = 'New Style Class C' class SubNewStyleClass(NewStyleClassB, NewStyleClassC): pass if __name__ == '__main__': print(SubNewStyleClass.mro()) print(SubNewStyleClass.var)
運(yùn)行結(jié)果不再符合廣度優(yōu)先:
[<class '__main__.SubNewStyleClass'>, <class '__main__.NewStyleClassB'>, <class '__main__.NewStyleClassA'>, <class '__main__.NewStyleClassC'>, <type 'object'>]
New Style Class A
可見,新式類的繼承順序并非廣度優(yōu)先,而是C3算法。至于C3算法,以后再另外詳細(xì)寫。
3.類實(shí)例類型的區(qū)別
在經(jīng)典類中,所有的類都是classobj類型,而類的實(shí)例都是instance類型。類與實(shí)例只有通過__class__屬性進(jìn)行關(guān)聯(lián)。這樣在判斷實(shí)例類型時,就會造成不便:所有的實(shí)例都是instance類型。
class A():pass class B():pass a = A() b = B() if __name__ == '__main__': print(type(a)) print(type(b)) print(type(a) == type(b))
type(a) == type(b)的結(jié)果永遠(yuǎn)為True,那這樣的比較就毫無意義。
更為麻煩的是,經(jīng)典類的實(shí)例是instance類型,而內(nèi)置類的實(shí)例卻不是,無法統(tǒng)一。
通過代碼判斷下內(nèi)置類型list的實(shí)例[1, 2, 3]是什么類型
print(type([1, 2, 3]))
運(yùn)行結(jié)果,是list類型
<type 'list'>
內(nèi)置類的實(shí)例類型和經(jīng)典類的實(shí)例類型完全不同,容易造成困惑,不利于代碼的統(tǒng)一。
這個問題在Python 3之后就不復(fù)存在了,因?yàn)镻ython3中所有的類都是新式類,新式類中類與類型已經(jīng)統(tǒng)一:類實(shí)例的類型是這個實(shí)例所創(chuàng)建自的類(通常是和類實(shí)例的__class__相同),而不再是Python 2.x版本中的“instance”實(shí)例類型。
更詳細(xì)的:http://chabaoo.cn/article/165048.htm
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
相關(guān)文章
基于Python實(shí)現(xiàn)圖片瀏覽器的應(yīng)用程序
圖像瀏覽器應(yīng)用程序是一種非常常見和實(shí)用的工具,這篇文章就來為大家介紹一下如何使用Python編程語言和wxPython庫創(chuàng)建一個簡單的圖像瀏覽器應(yīng)用程序,感興趣的可以了解下2023-10-10python自動截取需要區(qū)域,進(jìn)行圖像識別的方法
今天小編就為大家分享一篇python自動截取需要區(qū)域,進(jìn)行圖像識別的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05Python實(shí)現(xiàn)的基數(shù)排序算法原理與用法實(shí)例分析
這篇文章主要介紹了Python實(shí)現(xiàn)的基數(shù)排序算法,簡單說明了基數(shù)排序的原理并結(jié)合實(shí)例形式分析了Python實(shí)現(xiàn)與使用基數(shù)排序的具體操作技巧,需要的朋友可以參考下2017-11-11Python實(shí)現(xiàn)通過解析域名獲取ip地址的方法分析
這篇文章主要介紹了Python實(shí)現(xiàn)通過解析域名獲取ip地址的方法,結(jié)合實(shí)例形式總結(jié)分析了兩種比較常見的解析域名對應(yīng)IP地址相關(guān)操作技巧,需要的朋友可以參考下2019-05-05python3 實(shí)現(xiàn)的人人影視網(wǎng)站自動簽到
這里給大家分享的是使用Python3結(jié)合計(jì)劃任務(wù),實(shí)現(xiàn)的人人影視網(wǎng)站自動簽到功能的代碼,非常的實(shí)用,有需要的小伙伴可以參考下2016-06-06Tensorflow2.1 完成權(quán)重或模型的保存和加載
這篇文章主要為大家介紹了Tensorflow2.1 完成權(quán)重或模型的保存和加載,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11