
淺談python中的面向?qū)ο蠛皖惖幕菊Z(yǔ)法
當(dāng)我發(fā)現(xiàn)要寫python的面向?qū)ο蟮臅r(shí)候,我是躊躇滿面,坐立不安呀。我一直在想:這個(gè)坑應(yīng)該怎么爬?因?yàn)?a href='/map/python/' style='color:#000;font-size:inherit;'>python中關(guān)于面向?qū)ο蟮膬?nèi)容很多,如果要講透,最好是用面向?qū)ο蟮乃枷胫匦聦W(xué)一遍前面的內(nèi)容。這個(gè)坑是如此之大,猶豫再三,還是只撿一下重要的內(nèi)容來(lái)講吧,不足的內(nèi)容只能靠大家自己去補(bǔ)充了。
慣例聲明一下,我使用的版本是 python2.7,版本之間可能存在差異。
好,在開講之前,我們先思考一個(gè)問題,看代碼:
為什么我只創(chuàng)建是為 a 賦值,就可以使用一些我沒寫過(guò)的方法?
可能會(huì)有小伙伴說(shuō):因?yàn)?a 此時(shí)是個(gè)字符串對(duì)象呀,當(dāng)然能夠使用字符串的方法,至于這些方法,那是python事先寫好的。
好吧,那換個(gè)問題,為什么 python 知道它是個(gè)字符串對(duì)象?
在深入講這個(gè)問題之前,先記住一句話:python中一切皆對(duì)象,對(duì)象都是由類創(chuàng)建的。
那么類是什么東西呢?我在這舉個(gè)例子。
有一天,我在街上走著,突然看見前面有一個(gè)仇人。此時(shí)我想揍他一頓,但是力是相互作用的呀,打他我的拳頭也會(huì)疼。誒,此時(shí)我發(fā)現(xiàn)路邊有個(gè)石頭,大小形狀正合適,在不考慮警察叔叔怎么想的前提下,這是一個(gè)好的選擇。然后我抄起石頭,對(duì)著仇人進(jìn)行了一些好孩子不能模仿的行為,然后深藏功與名,收工回家。
在這個(gè)過(guò)程中,我們?yōu)槭裁磿?huì)知道那塊東西是石頭?
因?yàn)樗木哂惺^的外觀特征呀!
為什么我們會(huì)知道石頭可以砸人?
因?yàn)槭^硬呀!
為什么我們知道石頭是硬的?
因?yàn)?.....嗯.....小時(shí)候我爸告訴我的。
此時(shí)可以得到一個(gè)結(jié)論:我們知道一個(gè)東西是什么,具有什么功能,是因?yàn)槲覀兊哪X海中已經(jīng)有個(gè)這個(gè)東西的概念。而這個(gè)概念可能是從長(zhǎng)輩那里知道的,也可能是自己各種實(shí)驗(yàn)后自己總結(jié)的。類似于我們對(duì)于‘黑洞'這個(gè)東西的認(rèn)識(shí),還是科學(xué)家的各種研究總結(jié)而來(lái)。
如何將用石頭打人這個(gè)例子用代碼來(lái)實(shí)現(xiàn)的話:
class Stone(object): # 我創(chuàng)建一個(gè)叫Stone的類
def attack(self):
print '把頭伸過(guò)來(lái),我給你加個(gè)buff'
a = Stone() # 我用類創(chuàng)建了一個(gè)對(duì)象,也稱為類的實(shí)例化
a.attack() # 我使用這個(gè)對(duì)象的方法
很好,這樣我們就完成了我們的需要了。
如果我們?cè)賱?chuàng)建其他對(duì)象:
很顯然python并沒有為我們準(zhǔn)備 attack 方法,所以就用不了。
所謂的類只是一個(gè)抽象的定義,而實(shí)例則是具體的對(duì)象。它們之間的差別就想我腦海中的石頭和我手中的石頭一樣,只有后者才真實(shí)存在。當(dāng)然,這里不要跟我講什么唯心主義論什么的。
看到這里,關(guān)于類和對(duì)象之間的關(guān)系應(yīng)該清楚了一些。有些同學(xué)可能會(huì)問:python中的類都是我們事先寫好的,有沒有方法讓python自動(dòng)生成類,然后在特定的時(shí)候使用這些類呢?恭喜你,同學(xué),你可能摸到了人工智能的門檻了,如果能夠?qū)崿F(xiàn)的話,那和我們?nèi)祟惖膶W(xué)習(xí)能力不是差不多嗎?好吧,這只是我的一個(gè)設(shè)想,真正的人工智能要怎么實(shí)現(xiàn),我也不知道,還沒有這么高的水平去研究先,不過(guò)作為一名程序員,能夠編寫人工智能,可能是終身的追求了吧。
在講完類和實(shí)例化是怎么一回事之后,我們來(lái)看看類的基本語(yǔ)法。
首先,和定義函數(shù)的 def 一樣, class 是定義類的關(guān)鍵字。
緊接著的是類名,這個(gè)可以自定義,同樣的,不能和python的內(nèi)置關(guān)鍵字沖突。另外,建議避開python的內(nèi)建類型,例如 str、int之類的名字。規(guī)范的命名應(yīng)該遵從“駝峰命名法”,例如: MyClass 這里的命名,每個(gè)單詞的首字母大寫。
然后是一個(gè)括號(hào),里面的參數(shù)是用于繼承的,一般繼承于 object,表示一個(gè)新式類。另外,你可能見過(guò)沒有括號(hào)的寫法,這是經(jīng)典類的寫法。
示例:
class NewClass(object):
pass
class OldClass:
pass
New = NewClass() # 創(chuàng)建一個(gè)新式類的實(shí)例
Old = OldClass() # 創(chuàng)建一個(gè)經(jīng)典類的實(shí)例
這就是類的基本語(yǔ)法,當(dāng)然這樣還是不夠的,但是在更深入之前,我想先講一個(gè)新舊式類的差別。
在這里,我們先打印一下兩個(gè)變量的類型:
print type(New)
print type(Old)
可以看下兩者的輸出是不同的。
在早于python2.2的版本時(shí),只有經(jīng)典類這一種寫法,當(dāng)時(shí),類和類型沒有合并。
類是類對(duì)象,實(shí)例是實(shí)例對(duì)象,這兩個(gè)對(duì)象之間沒有任何關(guān)系。
這句話是什么意思?看代碼:
print type(OldClass)
print type(Old)
我們可以看見其輸出很含糊,經(jīng)典類屬于類對(duì)象,無(wú)論是哪個(gè)類,都統(tǒng)一為“類”類型,實(shí)例屬于實(shí)例類型,卻不知道其是由哪個(gè)類創(chuàng)建的,所以的實(shí)例都統(tǒng)一為“實(shí)例”類型。也就是說(shuō)當(dāng)時(shí)的類型用 classobj 和 instance 代表了所以的類和實(shí)例,無(wú)論你是哪個(gè)類,又或是哪個(gè)類創(chuàng)建的實(shí)例。
這樣的信息實(shí)在太少,而類和類型之間非?;靵y。為了解決這種情況,在 python2.2 中引入了新式類,并進(jìn)行了類和類型的同統(tǒng)一。
print type(NewClass)
print type(New)
類的類型是 type?type 返回的對(duì)象還能像類一樣創(chuàng)新新對(duì)象?
總結(jié)的來(lái)說(shuō):在新式類中,所以的類對(duì)象都是 type 的實(shí)例。而不同的類對(duì)象有能創(chuàng)建出其對(duì)應(yīng)的實(shí)例。
class NewClass(object):
def __init__(self, val):
self.val = val
New = NewClass(123)
b = type(New)(321) # 對(duì)實(shí)例來(lái)說(shuō)type返回的是類對(duì)象,我又可以用類對(duì)象來(lái)和創(chuàng)建新的實(shí)例
print b.val
構(gòu)造器方法
一般可以理解類中的函數(shù)就是方法,而方法分為:實(shí)例方法,只有實(shí)例化后才能調(diào)用的,其第一個(gè)參數(shù)一般為 self,代表實(shí)例本身;類方法,其第一個(gè)參數(shù)為 cls,代表類本身;還有靜態(tài)方法,就是個(gè)普通函數(shù),沒有要求參數(shù)。
1. __init__(self [,arg1,....]):
當(dāng)類被調(diào)用進(jìn)行實(shí)例化的時(shí)候,python會(huì)自動(dòng)調(diào)用類里面的構(gòu)造函數(shù)(如果有的話),在構(gòu)造函數(shù)中,可以進(jìn)行各種初始化的操作,最常見的就是上面的進(jìn)行實(shí)例的屬性的創(chuàng)建。
python 在示例化的時(shí)候,會(huì)檢查其實(shí)行了 __init__ 方法了沒有,如果沒有則不對(duì)實(shí)例進(jìn)行任何操作,然后返回對(duì)象。如果實(shí)行了這個(gè)方法,則自動(dòng)調(diào)用這個(gè)方法,并自動(dòng)將 self 傳進(jìn)行,也就是說(shuō)我們?cè)趯?shí)例化進(jìn)行傳參的時(shí)候,將不用理會(huì) self,直接傳給后面的參數(shù)。
講到屬性,就必須要提一下什么是屬性。屬性這個(gè)對(duì)象其實(shí)更像一個(gè)變量,大多數(shù)對(duì)象都可以有屬性(不包括python的內(nèi)置類型),例如函數(shù)。
def Test():
pass
Test.a = 123
print Test.a
因?yàn)楹瘮?shù)也是一個(gè)對(duì)象。
屬性在類中,就是一個(gè)變量,例如:
class NewClass(object):
a = 123
print NewClass.a
當(dāng)然,因?yàn)?python 的特性,我們可以在運(yùn)作中為某個(gè)對(duì)象添加屬性,而不用一開始就在類中寫定。
注意,這個(gè)方法應(yīng)該返回 None,也就是說(shuō)我們一般不用 return 任何對(duì)象,讓它默認(rèn)返回就行了。
2. __new__(cls [,arg1,....]):
這也是一個(gè)構(gòu)造器方法,它是一個(gè)類方法,一般在對(duì) python 的不可變數(shù)據(jù)類型進(jìn)行繼承擴(kuò)展的時(shí)候用的比較多。
某處拿來(lái)的代碼示例:
class RoundFloat(float):
def __new__(cls, val):
return super(RoundFloat, cls).__new__(cls, round(val, 2))
a = RoundFloat(3.14159)
print a
解構(gòu)器方法
__del__(self [,arg1,....])
這個(gè)方法將會(huì)在對(duì)象所以的引用被清除后才執(zhí)行,例如:
class Test(object):
def __del__(self):
print '我被干掉了,兄弟們?yōu)槲覉?bào)仇!'
a = Test() # 創(chuàng)建了一個(gè)對(duì)象
b = a # b又引用了a
c = b # c又引用了b,現(xiàn)在 a 所指向的對(duì)象有3次引用,相當(dāng)有三條命
del a # 干掉一條命
del b # 又干掉
del c # 聽說(shuō)你有3條命?全部干掉!
注意,這里只輸出了一次,也就是說(shuō)到了最后才刪除完畢。這里要注意一下幾點(diǎn):
1.調(diào)用 del 并不意味著完成刪除某個(gè)對(duì)象,只是減少引用。
2.如果你有一個(gè)循環(huán)引用或其它的原因,讓一個(gè)實(shí)例的引用逗留不去,該對(duì)象的__del__()可能永遠(yuǎn)不會(huì)被執(zhí)行。
3.__del__()未捕獲的異常會(huì)被忽略掉(因?yàn)橐恍┰赺_del__()用到的變量或許已經(jīng)被刪除了)。 不要在__del__()中干與實(shí)例沒任何關(guān)系的事情。
4.一般情況下并不用實(shí)現(xiàn)這個(gè)方法,因?yàn)檫@樣有一定的風(fēng)險(xiǎn)。
5.如果你定義了__del__,并且實(shí)例是某個(gè)循環(huán)的一部分,垃圾回收器將不會(huì)終止這個(gè)循環(huán)— —你需要自已顯式調(diào)用 del。
6.如果繼承了父類,且父類中也有解構(gòu)器,要記得調(diào)用。否則可能會(huì)有某些在父類中的清理方法沒有調(diào)用到,出現(xiàn)以下無(wú)法預(yù)料的錯(cuò)誤。
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
LSTM 模型輸入長(zhǎng)度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長(zhǎng)序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報(bào)考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計(jì)的實(shí)用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠(chéng)摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實(shí)施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價(jià)值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡(jiǎn)稱 BI)深度融合的時(shí)代,BI ...
2025-07-10SQL 在預(yù)測(cè)分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢(shì)預(yù)判? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代,預(yù)測(cè)分析作為挖掘數(shù)據(jù)潛在價(jià)值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價(jià)值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點(diǎn),而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報(bào)考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭(zhēng)搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢(shì)性檢驗(yàn):捕捉數(shù)據(jù)背后的時(shí)間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢(shì)性檢驗(yàn)如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時(shí)間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時(shí)間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實(shí)戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗(yàn):數(shù)據(jù)趨勢(shì)與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢(shì)變化以及識(shí)別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國(guó)內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對(duì)策略? 長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨(dú)特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計(jì)學(xué)方法在市場(chǎng)調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場(chǎng)調(diào)研是企業(yè)洞察市場(chǎng)動(dòng)態(tài)、了解消費(fèi)者需求的重要途徑,而統(tǒng)計(jì)學(xué)方法則是市場(chǎng)調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動(dòng)力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動(dòng)力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價(jià)值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03