人工智能火了,Python跟著再一次火了。那Python之父了解一下。
創(chuàng)新互聯(lián)公司-云計(jì)算及IDC服務(wù)提供商,涵蓋公有云、IDC機(jī)房租用、成都服務(wù)器托管、等保安全、私有云建設(shè)等企業(yè)級互聯(lián)網(wǎng)基礎(chǔ)服務(wù),溝通電話:028-86922220
吉多·范羅蘇姆1956年1月31日出生于荷蘭。
1982年獲得阿姆斯特丹大學(xué)的數(shù)學(xué)和計(jì)算機(jī)科學(xué)的碩士學(xué)位。
1991年初,吉多·范羅蘇姆發(fā)布了Python的第一個(gè)公開發(fā)行版。
1995移居到美國。
2005年加入Google公司,其中有一半時(shí)間是花在Python上。
2006年,他被美國計(jì)算機(jī)協(xié)會(huì)(ACM)認(rèn)定為著名工程師。
大師加入谷歌的那一年,他49歲,谷歌老板,拉里佩奇33歲。
兩種方法解決:
- 第一種
class A:
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
#這一行解決了問題
A.__init__(self)
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
第二種:
#父類需要繼承object對象
class A(object):
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
#這一行解決問題
super(B,self).__init__()
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS:讓類A繼承自object類,這樣才能使用super函數(shù),因?yàn)檫@是python的“新式類”支持的特性。當(dāng)前的class和對象可以作為super函數(shù)的參數(shù)使用,調(diào)用函數(shù)返回的對象的任何方法都是調(diào)用超類的方法,而不是當(dāng)前類的方法。
優(yōu)劣:
- 方法一更直觀,方法二可以一次初始化所有超類
- super函數(shù)比在超類中直接調(diào)用未綁定方法更直觀,但是其最大的優(yōu)點(diǎn)是如果子類繼承了多個(gè)父類,它只需要使用一次super函數(shù)就可以。然而如果沒有這個(gè)需求,直接使用A.init(self)更直觀一些。
在繼承關(guān)系中,我們想調(diào)用已經(jīng)被覆蓋了的父類的方法,就需要如下實(shí)現(xiàn):
解決方法:
要調(diào)用父類中的方法,就要使用超類(超集)方法super(),該方法旨在調(diào)用已經(jīng)被覆蓋的父類的成員方法。
討論:
有關(guān)python是如何實(shí)現(xiàn)繼承的?
針對每一個(gè)定義的類,都會(huì)計(jì)算出一個(gè)成為方法解析順序(MRO)的元組,其只是簡單的對所有基類進(jìn)行簡單地線性排列。
通過上述的C類調(diào)用MRO表,我們不難看出,它將本類開始一直到object類直接所有的父類一次性從左向右逐層向上的排列了出來(先排列自己,在排列自己的父類,最后排列父類的父類,以及最后的object)
然而MRO為何如此排列,這里要涉及到一個(gè)非常令人討厭的數(shù)學(xué)算法,C3線性化處理,這里只是總結(jié)其三個(gè)約束:(簡單點(diǎn)說,其實(shí)就是對父類進(jìn)行歸并排列)
1、先檢查子類,再檢查父類
2、有多個(gè)父類時(shí),按照MRO表的順序依次查看
3、如果下一個(gè)待選的類出現(xiàn)了兩個(gè)合法的選擇,那么就從第一個(gè)父類中選取。
4、補(bǔ)充一點(diǎn):MRO對類的排序幾乎適用于任何定義的類層次結(jié)構(gòu)。
來了來了,它真的來了:重點(diǎn)~~
有很多同學(xué)是否仔細(xì)看過上邊的代碼?
有關(guān)super()函數(shù),以下重點(diǎn)需要各位明白:
在重寫的方法中僅使用一次super()方法時(shí),會(huì)按照MRO表從下一個(gè)類開始搜索對應(yīng)的方法或?qū)傩裕源祟愅啤?所以C中重寫了父類的構(gòu)造,構(gòu)造中有super,所以會(huì)按照順序去查找MRO中下一個(gè)類的方法,發(fā)現(xiàn)A中也有super,就會(huì)再去B中找對應(yīng)的方法(同名方法是__init__),所以找到B的構(gòu)造,可是B中又有super,就會(huì)再去MRO中B的下一個(gè)類(Base)中找對應(yīng)的方法(Base的__init__()方法),所以會(huì)先打印“Base.__init__”,打印完后又因?yàn)锽的__init__中還有打印“B.__init__”,所以接著打印‘B.__init__’,又因?yàn)榇蛴⊥旰驛中還有打印“A.__init__”,所以再打印“A.__init__”,最后打印“C.__init__”。這樣就可以遍歷MRO整張表中所有的對應(yīng)的__init__()方法,并且讓每個(gè)方法只會(huì)被調(diào)用一次。
為了更好的記憶:當(dāng)所有重寫的方法中只使用了一次super函數(shù)時(shí),會(huì)從最上層的類依次調(diào)用其指定的方法即可以理解為(object-Base-B-A-C)。
所以,輸出結(jié)果為:
甚至于如下情況更為耐人尋味,仔細(xì)品一品:
值的一提的是:AB均沒有顯式的繼承的父類,為何結(jié)果為打印‘AB’呢?這里就要理解MRO的含義了哦!
你好,請看下面的例子和說明:python中類的初始化方法是__init__(),因此父類子類的初始化方法都是這個(gè),如果子類不實(shí)現(xiàn)這個(gè)函數(shù),初始化時(shí)調(diào)用父類的初始化函數(shù),如果子類實(shí)現(xiàn)這個(gè)函數(shù),就覆蓋了父類的這個(gè)函數(shù),既然繼承父類,就要在這個(gè)函數(shù)里顯式調(diào)用一下父類的__init__(),這跟C++,jAVA不一樣,他們是自動(dòng)調(diào)用父類初始化函數(shù)的。調(diào)用父類函數(shù)有以下方法:class A:def method(self, arg):pass
class B(A):def method(self, arg):# A.method(self,arg) # 1# super(B, self).method(arg) #2super().method(arg) #31.直接寫類名調(diào)用2.用super(type,obj).method(arg)方法調(diào)用。3.在類定義中調(diào)用本類的父類方法,可以直接super().method(arg).在代碼中調(diào)用對象的父類的方法的示例:ob = B()super(B,ob).method(arg) #調(diào)用class B的父類class A的method。初始化中調(diào)用父類初始化方法示例:class B(A):
在對于python中類的使用上,我們分出了子類和父類兩種。對于這二者之間的關(guān)系,我們可以簡單理解為繼承。不過python中加入了實(shí)例的討論,那么對于繼承后的子類來說,父類的實(shí)例是否被繼承又是我們所需要思考的問題。下面我們就子類和父類進(jìn)行簡單介紹,然后就二者之間的繼承關(guān)系重點(diǎn)分析。
1.概念
子類和父類主要描述的是類之間的繼承關(guān)系,即所屬關(guān)系。繼承的類可在被繼承的類的基礎(chǔ)上添加格外的參數(shù)和行為,新類稱為子類,擴(kuò)展類;被繼承的類稱為基類、父類或者超類。
2.繼承關(guān)系
子類與父類的關(guān)系是 “is” 的關(guān)系,如上 Cat 繼承于 Animal 類,我們可以說:
“A”是 Animal 類的實(shí)例,但,“A”不是 Cat 類的實(shí)例。
“C”是 Animal 類的實(shí)例,“C”也是 Cat 類的實(shí)例。
判斷對象之間的關(guān)系,我們可以通過 isinstance (變量,類型) 來進(jìn)行判斷:
print('"A" IS Animal?', isinstance(A, Animal))
print('"A" IS Cat?', isinstance(A, Cat))
print('"C" IS Animal?', isinstance(C, Animal))
print('"C" IS Cat?', isinstance(C, Cat))
Python實(shí)現(xiàn)子類調(diào)用父類的方法
python和其他面向?qū)ο笳Z言類似,每個(gè)類可以擁有一個(gè)或者多個(gè)父類,它們從父類那里繼承了屬性和方法。如果一個(gè)方法在子類的實(shí)例中被調(diào)用,或者一個(gè)屬性在子類的實(shí)例中被訪問,但是該方法或?qū)傩栽谧宇愔胁⒉淮嬖冢敲淳蜁?huì)自動(dòng)的去其父類中進(jìn)行查找。
繼承父類后,就能調(diào)用父類方法和訪問父類屬性,而要完成整個(gè)集成過程,子類是需要調(diào)用的構(gòu)造函數(shù)的。
子類不顯式調(diào)用父類的構(gòu)造方法,而父類構(gòu)造函數(shù)初始化了一些屬性,就會(huì)出現(xiàn)問題
如果子類和父類都有構(gòu)造函數(shù),子類其實(shí)是重寫了父類的構(gòu)造函數(shù),如果不顯式調(diào)用父類構(gòu)造函數(shù),父類的構(gòu)造函數(shù)就不會(huì)被執(zhí)行,導(dǎo)致子類實(shí)例訪問父類初始化方法中初始的變量就會(huì)出現(xiàn)問題。
子類調(diào)用父類函數(shù)有以下方法:
直接寫類名調(diào)用
用 super(type, obj).method(arg)方法調(diào)用。
在類定義中調(diào)用本類的父類方法,可以直接用super().method(arg)
1
2
3
4
5
6
7
8
9
class A:
def method(self, arg):
pass
class B(A):
def method(self, arg):
# A.method(self,arg) # 1
# super(B, self).method(arg) # 2
super().method(arg) # 3
網(wǎng)站欄目:python函數(shù)父,父與子python
URL地址:http://chinadenli.net/article32/hesopc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、網(wǎng)站策劃、電子商務(wù)、品牌網(wǎng)站設(shè)計(jì)、全網(wǎng)營銷推廣、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)