2018-10-08

遞歸函數(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í)緩沖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容