遞歸函數(shù)
在函數(shù)內(nèi)部,可以調(diào)用其他函數(shù)。如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身本身,這個(gè)函數(shù)就是遞歸函數(shù)。
??:
計(jì)算?階乘 n!=1 x 2 x 3 x ... x n?
用函數(shù) fact?(n)表達(dá)
fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact?(n-1)??x n

??優(yōu)點(diǎn):
定義簡(jiǎn)單,?邏輯清晰。?理論上所有的遞歸函數(shù)都可以寫成循環(huán)的方式,但循環(huán)邏輯不如遞歸清晰。
??缺點(diǎn):
過(guò)深的調(diào)用會(huì)導(dǎo)致棧溢出。
?? 使用遞歸函數(shù)需要注意防止棧溢出。在計(jì)算機(jī)中,函數(shù)調(diào)用是通過(guò)棧(stack)這種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,每當(dāng)進(jìn)入一個(gè)函數(shù)調(diào)用,棧就會(huì)加一層棧幀,每當(dāng)函數(shù)返回,棧就會(huì)減一層棧幀。由于棧的大小不是無(wú)限的,所以,遞歸調(diào)用的次數(shù)過(guò)多,會(huì)導(dǎo)致棧溢出
解決遞歸調(diào)用棧溢出的方法就是涌過(guò)?尾遞歸優(yōu)化?,?事實(shí)上尾遞歸 和循環(huán)效果是一樣的,?所以 吧循環(huán)看成一種特殊的尾遞歸函數(shù)也可以。
尾遞歸是指,?在函數(shù)返回的時(shí)候,調(diào)用本身,?并且,?return 語(yǔ)句不能包含表達(dá)式。?這樣編譯器就可以將 尾遞歸做優(yōu)化,?是遞歸本身無(wú)論調(diào)用多少次 都使用一個(gè)棧幀,?不會(huì)出翔幀溢出的情況。
針對(duì)尾遞歸優(yōu)化的語(yǔ)言可以通過(guò)尾遞歸防止棧溢出。尾遞歸事實(shí)上和循環(huán)是等價(jià)的,沒(méi)有循環(huán)語(yǔ)句的編程語(yǔ)言只能通過(guò)尾遞歸實(shí)現(xiàn)循環(huán)。
Python?標(biāo)準(zhǔn)的解釋器沒(méi)有針對(duì)尾遞歸做優(yōu)化,任何遞歸函數(shù)都存在棧溢出的問(wèn)題。
?IO?編程
由于程序和運(yùn)行時(shí)數(shù)據(jù)是在內(nèi)存中駐留,由?CPU?這個(gè)超快的計(jì)算核心來(lái)執(zhí)行,涉及到數(shù)據(jù)交換的地方,通常是磁盤、網(wǎng)絡(luò)等,就需要?IO?接口。
有兩種?IO?模式 ??
??同步?IO?與 異步?IO?
??第一種是CPU等著,也就是程序暫停執(zhí)行后續(xù)代碼,等100M的數(shù)據(jù)在10秒后寫入磁盤,再接著往下執(zhí)行,這種模式稱為同步IO;
??另一種方法是CPU不等待,只是告訴磁盤,“您老慢慢寫,不著急,我接著干別的事去了”,于是,后續(xù)代碼可以立刻接著執(zhí)行,這種模式稱為異步IO。
使用異步IO來(lái)編寫程序性能會(huì)遠(yuǎn)遠(yuǎn)高于同步IO,但是異步IO的缺點(diǎn)是編程模型復(fù)雜。
文件的讀寫
讀文件模式打開(kāi)文件對(duì)象?使用 python 內(nèi)置 open?()?函數(shù) 傳入文件名和 標(biāo)識(shí)符即可
打開(kāi)后,?調(diào)用 read()方法可以一次性讀取文件全部?jī)?nèi)容,?python 會(huì)把內(nèi)容讀到內(nèi)存,?用一個(gè) str 對(duì)象表示:
???由于文件讀寫時(shí)都有可能產(chǎn)生IOError,一旦出錯(cuò),后面的f.close()就不會(huì)調(diào)用。所以,為了保證無(wú)論是否出錯(cuò)都能正確地關(guān)閉文件,我們可以使用try ... finally來(lái)實(shí)現(xiàn):
最后?調(diào)用 close?()?關(guān)閉文件?「因?yàn)槲募?duì)象會(huì)占用操作系的資源,?并且操作系統(tǒng)統(tǒng)一時(shí)間可以打開(kāi)文件的數(shù)量也是有限的」
由于一直調(diào)用太頻繁 所以 python 引入了 with 語(yǔ)句 來(lái)自動(dòng)幫助?調(diào)用 close?方法
調(diào)用?read?(?)?會(huì)一次性讀取文件的全部?jī)?nèi)容,如果文件有?10G,內(nèi)存就爆了,所以,要保險(xiǎn)起見(jiàn),可以反復(fù)調(diào)用?read?(?size?)?方法,每次最多讀取?size?個(gè)字節(jié)的內(nèi)容。另外,調(diào)用?readline(?)?可以每次讀取一行內(nèi)容,調(diào)用?readlines?(?)?一次讀取所有內(nèi)容并按行返回?list。因此,要根據(jù)需要決定怎么調(diào)用。
?? 如果文件很小,read?(?)?一次性讀取最方便;如果不能確定文件大小,反復(fù)調(diào)用?read?(size)?比較保險(xiǎn);如果是配置文件,調(diào)用?readlines(?)?最方便
file-like Object
像?open(?)?函數(shù)返回的這種有個(gè)?read(?)?方法的對(duì)象,在?Python?中統(tǒng)稱為?file-like Object。除了?file外,還可以是內(nèi)存的字節(jié)流,網(wǎng)絡(luò)流,自定義流等等。file-like Objec?t不要求從特定類繼承,只要寫個(gè)read(?)?方法就行。
StringIO?就是在內(nèi)存中創(chuàng)建的?file-like Object,常用作臨時(shí)緩沖。