版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
從Python開始學(xué)編程目錄\h第1章用編程改造世界\h1.1從計算機到編程\h1.2所謂的編程,是做什么的\h1.3為什么學(xué)Python\h1.4最簡單的HelloWorld\h附錄APython的安裝與運行\(zhòng)h附錄Bvirtualenv\h第2章先做鍵盤俠\h2.1計算機會算術(shù)\h2.2計算機記性好\h2.3計算機懂選擇\h2.4計算機能循環(huán)\h附錄A小練習(xí)\h附錄B代碼規(guī)范\h第3章過程大于結(jié)果\h3.1懶人炒菜機\h3.2參數(shù)傳遞\h3.3遞歸\h3.4引入那把寶劍\h3.5異常處理\h附錄A搜索路徑的設(shè)置\h附錄B安裝第三方模塊\h附錄C代碼規(guī)范\h第4章朝思暮想是對象\h4.1輕松看對象\h4.2繼承者們\h4.3那些年,錯過的對象\h4.4意想不到的對象\h附錄A代碼規(guī)范\h第5章對象帶你飛\h5.1存儲\h5.2一寸光陰\h5.3看起來像那樣的東西\h5.4Python有網(wǎng)癮\h5.5寫一個爬蟲\h第6章與對象的深入交往\h6.1一切皆對象\h6.2屬性管理\h6.3我是風(fēng)兒,我是沙\h6.4內(nèi)存管理\h第7章函數(shù)式編程\h7.1又見函數(shù)\h7.2被解放的函數(shù)\h7.3小女子的梳妝匣\h7.4高階函數(shù)\h7.5自上而下第1章用編程改造世界1.1從計算機到編程1.2所謂的編程,是做什么的1.3為什么學(xué)Python1.4最簡單的HelloWorld附錄APython的安裝與運行附錄Bvirtualenv本章將簡要介紹計算機和編程的歷史。從計算機出現(xiàn)以來,硬件性能得到飛躍式的發(fā)展。與此同時,編程語言也幾經(jīng)變遷,產(chǎn)生了多種編程范式。Python語言以簡潔靈活的特點,在諸多編程語言中打下一片天地。通過歷史,我們不但能體驗Python的特色,還能了解這門語言想要解決的痛點。本章將以一個簡單的“HelloWorld!”程序結(jié)束,從此開啟Python之旅。1.1從計算機到編程人能運算和記憶,但更了不起的是善于借用工具。人類很早就開始利用方法和工具,輔助計算和記憶這樣高度復(fù)雜的認(rèn)知活動。古人用給繩子打結(jié)的方式來記錄圈養(yǎng)的牛羊,我們的祖先很早就能以眼花繚亂的速度使用算盤。隨著近代工業(yè)化的發(fā)展,社會對計算的需求越來越強烈。收稅需要計算,造機器需要計算,開挖運河也需要計算。新的計算工具不斷出現(xiàn)。利用對數(shù)原理,人們制造出計算尺。計算尺可以平行移動尺子來計算乘除法。19世紀(jì)的英國人巴貝奇設(shè)計了一臺機器,用齒輪的組合來進(jìn)行高精度的計算,隱隱預(yù)示著機器計算的到來。20世紀(jì)初有了機電式的計算機器。電動馬達(dá)驅(qū)動變檔齒輪“咯吱”轉(zhuǎn)動,直到得到計算結(jié)果。二戰(zhàn)期間,戰(zhàn)爭刺激了社會的計算需求。武器設(shè)計需要計算,比如坦克的設(shè)計、潛艇的外形、彈道的軌跡。社會的軍事化管理需要計算,比如火車調(diào)度、資源調(diào)配、人口動員。至于導(dǎo)彈和核彈這樣的高科技項目,更需要海量的計算。美國研制原子彈的曼哈頓計劃,除了使用IBM的計算機器外,還雇傭了許多女孩子進(jìn)行手工運算。計算本身甚至可以成為武器。電影《模仿游戲》就講述了英國數(shù)學(xué)家阿蘭·圖靈(AlanMathisonTuring)破解德國傳奇密碼機的故事。圖靈的主要工具,就是機電式的計算機器。值得一提的是,正是這位圖靈,提出了通用計算機的理論概念,為未來的計算機發(fā)展做好了理論準(zhǔn)備?,F(xiàn)在,計算機學(xué)科的最高獎項就以圖靈命名,以紀(jì)念他的偉大貢獻(xiàn)。德國工程師康拉德·楚澤(KonradZuse)發(fā)明的Z3計算機能編寫程序。這看起來已經(jīng)是一臺現(xiàn)代計算機的雛形了。計算工具的發(fā)展是漸進(jìn)的。不過歷史把第一臺計算機的桂冠頒給了戰(zhàn)后賓夕法尼亞大學(xué)研制的埃尼阿克(ENIAC,ElectronicNumericalIntegratorAndComputer)。埃尼阿克借鑒了前任的經(jīng)驗,遠(yuǎn)非橫空出世的奇跡。但它最重要的意義,是向人們展示了高速運算的可能性。首先它是一臺符合圖靈標(biāo)準(zhǔn)的通用計算機,能通過編程來執(zhí)行多樣的計算任務(wù)。其次,與機電式計算機器不同,埃尼阿克大量使用真空管,從而能快速運算。埃尼阿克的計算速度比之前的機電型機器提高了一千倍,這是一次革命性的飛躍。因此,即便計算輔助工具同樣歷史悠久,但人們?nèi)哉J(rèn)為埃尼阿克引領(lǐng)了一個新的時代—計算機時代。從埃尼阿克開始,計算機經(jīng)歷了迅猛的發(fā)展。計算機所采用的主要元件,從真空管變成大規(guī)模集成電路。計算機的運算性能,每一兩年的時間就會翻倍。但計算機的大體結(jié)構(gòu),都采用了馮·諾依曼體系。這一體系是長期演化的結(jié)果,但馮·諾依曼進(jìn)行了很好的總結(jié)。按照馮·諾依曼的設(shè)計,計算機采用二進(jìn)制運算,包括控制器、運算器、存儲器、輸入設(shè)備和輸出設(shè)備五個部分,如圖1-1所示。五個部分相互配合,執(zhí)行特定的操作,即指令。這五個部分各有分工。圖1-1馮·諾依曼結(jié)構(gòu)控制器:計算機的指揮部,管理計算機其他部分的工作,決定執(zhí)行指令的順序,控制不同部件之間的數(shù)據(jù)交流。運算器:顧名思義,這是計算機中進(jìn)行運算的部件。除加減乘除之類的算數(shù)運算外,還能進(jìn)行與、或、非之類的邏輯運算。運算器與控制器一起構(gòu)成了中央處理器(CPU,CentralProcessingUnit)。存儲器:存儲信息的部件。馮·諾依曼根據(jù)自己在曼哈頓工程中的經(jīng)驗,提出了存儲器不但要記錄數(shù)據(jù),還要記錄所要執(zhí)行的程序。輸入設(shè)備:向計算機輸入信息的設(shè)備,如鍵盤、鼠標(biāo)、攝像頭等。輸出設(shè)備:計算機向外輸出信息的設(shè)備,如顯示屏、打印機、音響等。人們最常想到的計算機是臺式機和筆記本電腦。其實,計算機還存在于智能手機、汽車、家電等多種設(shè)備中。但無論外形如何多變,這些計算機都沿襲了馮·諾依曼結(jié)構(gòu)。不過在具體細(xì)節(jié)上,計算機之間又有很大的差別。有的計算機使用了多級緩存,有的計算機只有鍵盤沒有鼠標(biāo),有的計算機用磁帶存儲。計算機的硬件是一門很龐雜的學(xué)問。幸運的是,計算機用戶大多不需要和硬件直接打交道。這一點是操作系統(tǒng)(OperatingSystem)的功勞。操作系統(tǒng)是運行在計算機上的一套軟件,負(fù)責(zé)管理計算機的軟硬件資源。有的時候我們請人修電腦,他可能會說“電腦需要重裝一下”。這個“重裝”,就是重新安裝操作系統(tǒng)的意思。無論是微軟的Windows,還是蘋果的iOS,都屬于操作系統(tǒng)。我們編程時,大多數(shù)時候都是通過操作系統(tǒng)這個“中間商”來和硬件打交道的。操作系統(tǒng)提供了一套系統(tǒng)調(diào)用(SystemCall),如圖1-2所示,規(guī)定了操作系統(tǒng)支持哪些操作。當(dāng)調(diào)用某個系統(tǒng)調(diào)用時,計算機會執(zhí)行對應(yīng)的操作。這就像是按下鋼琴上的一個鍵,鋼琴就會發(fā)出對應(yīng)的音律一樣。系統(tǒng)調(diào)用提供的功能非常基礎(chǔ),有時調(diào)用起來很麻煩。操作系統(tǒng)因此定義一些庫函數(shù)(LibraryRoutine),將系統(tǒng)調(diào)用組合成特定的功能,如同幾個音律組成的和弦。所謂的編程,就是用這些音律和和弦,來組成一首美妙的音樂。圖1-2硬件、操作系統(tǒng)和應(yīng)用程序的關(guān)系1.2所謂的編程,是做什么的編程中總是在調(diào)用計算機的基本指令。如果完全用基礎(chǔ)指令來說明所有的操作,代碼將超乎想象的冗長。IBM前總裁小沃森的自傳中就提到,他看到一位工程師想要做乘法運算,輸入程序用的打孔卡疊起來有1.2米高。幸好,程序員漸漸發(fā)現(xiàn),許多特定的指令組合會重復(fù)出現(xiàn)。如果能在程序中復(fù)用這些代碼,則可以節(jié)省很多工作量。復(fù)用代碼的關(guān)鍵是封裝(Packaging),即把執(zhí)行特殊功能的指令打包成一個程序塊,然后給這個程序塊起個容易查詢的名字。如果需要重復(fù)使用這個程序塊,則可以簡單地通過名字調(diào)用。就好像食客在點菜時,只需告訴廚師做“魚香肉絲”,而不需要具體說明要多少肉、多少調(diào)料、烹制多久一樣。剛才提到的操作系統(tǒng),就是將一些底層的硬件操作組合封裝起來,供上層的應(yīng)用程序調(diào)用。當(dāng)然,封裝是有代價的,它會消耗計算機資源。如果使用的是早期的計算機的話,封裝和調(diào)用的過程會非常耗時,最終得不償失。封裝代碼的方式也有很多種。根據(jù)不同的方式,程序員寫程序時要遵循特定的編程風(fēng)格,如面向過程編程、面向?qū)ο缶幊毯秃瘮?shù)式編程。用更嚴(yán)格的術(shù)語來說,每種編程風(fēng)格都是一種編程范式(ProgrammingParadigm)。編程語言開始根據(jù)編程范式區(qū)分出陣營,面向過程的C語言、面向?qū)ο蟮腏ava語言、面向函數(shù)的Lisp語言等。任何一種編程范式編寫出來的程序,最終都會翻譯成上面所述的簡單功能組合。所以編程的需求總是可以通過多種編程范式來分別實現(xiàn),區(qū)別只在于這個范式的方便程度而已。由于不同的范式各有利弊,所以現(xiàn)代不少編程語言都支持多種編程范式,以便程序員在使用時取舍。Python就是一門多范式語言。某一范式的代表性語言,也開始在新版本中支持其他范式。原本屬于面向?qū)ο蠓妒降腏ava語言,就在新版本中也開始加入函數(shù)式編程的特征。編程范式是學(xué)習(xí)編程的一大攔路虎。對于一個程序員來說,如果他熟悉了某一種編程范式,那么他就能很容易地上手同一范式的其他編程語言。對于一個新手來說,一頭扎進(jìn)Python這樣的多范式語言,會發(fā)現(xiàn)同一功能有不同的實現(xiàn)風(fēng)格,不免會感到困惑。一些大學(xué)的計算機專業(yè)課程,選擇了分別講授代表性的范式語言,比如C、Java、Lisp,以便學(xué)生在未來學(xué)習(xí)其他語言時有一個好的基礎(chǔ)。但這樣的做法,會將學(xué)習(xí)過程拉得很漫長。在我看來,Python這樣的多范式語言提供了一個對比學(xué)習(xí)多種編程范式的機會。在同一語言框架下,如果程序員能清晰地區(qū)分出不同的編程范式,并了解各自的利弊,將起到事半功倍的效果。這也是本書中想要做到的,從面向過程、面向?qū)ο?、函?shù)式三種主流范式出發(fā),在一本書的篇幅內(nèi)學(xué)三遍Python。這樣的話,讀者將不止是學(xué)會了一門Python語言,還能為未來學(xué)習(xí)其他語言打好基礎(chǔ)。學(xué)習(xí)了包括Python在內(nèi)的任何一門編程語言后,就打開了計算機世界的大門。通過編程,你幾乎可以發(fā)揮出計算機所有的功能,給創(chuàng)造力提供了廣闊的施展空間。想到某個需求,比如統(tǒng)計金庸小說中的詞頻,自己就能寫程序解決。有了不錯的想法,例如想建立一個互助學(xué)習(xí)的網(wǎng)站,也可以立即打開電腦動手編寫。一旦學(xué)會了編程,你會發(fā)現(xiàn),軟件主要比拼的就是大腦和時間,其他方面的成本都極為低廉。編寫出的程序還會有許多回報??梢允墙?jīng)濟性的回報,比如獲得高工資,比如創(chuàng)立一家上市的互聯(lián)網(wǎng)企業(yè)。也可以是聲譽性的回報,比如做出了很多人喜愛的編程軟件,比如攻克了困擾編程社區(qū)的難題等。正如《黑客與畫家》一書中所說,程序員是和畫家一樣的創(chuàng)作者。無窮的創(chuàng)造機會,正是編程的一大魅力所在。編程是人與機器互動的基本方式。人們通過編程來操縱機器。從18世紀(jì)的工業(yè)革命開始,人們逐漸擺脫了手工業(yè)的生產(chǎn)方式,開始轉(zhuǎn)向機器生產(chǎn)。機器最開始用于棉紡工業(yè),一開始紡出的紗線質(zhì)量比不上手工紡制的。但機器可以晝夜工作,不知疲倦,產(chǎn)量也是驚人。因此,到了18世紀(jì)末,全球大部分的棉布都變成了機器生產(chǎn)。如今,機器在生活中已經(jīng)屢見不鮮。人工智能這樣的“軟性機器”,也越來越多地進(jìn)入生產(chǎn)和生活。工人用機器來制造手機、醫(yī)生操縱機器來進(jìn)行微創(chuàng)手術(shù)、交易員用機器進(jìn)行高頻的股票交易。殘酷一點講,對機器的調(diào)配和占有能力,將會取代血統(tǒng)和教育,成為未來階級區(qū)分的衡量標(biāo)準(zhǔn)。這也是編程教育變得越來越重要的原因。機器世界的變化,正在改變世界的工作格局。重復(fù)性工作消亡,程序員的需求量卻在不斷加大。很多人都在自學(xué)編程,以便跟上潮流。幸好,編程也變得越來越簡單。從匯編語言,到C語言,再到Python語言,編程語言越來越親民。以Python為例,在豐富的模塊支持下,一個功能的實現(xiàn)只需要寥寥幾個接口的調(diào)用,不需要費太多工夫。我們之前所說的封裝,也是把功能給打包成規(guī)范的接口,讓別人用起來覺得簡單。編程用精準(zhǔn)的機器為大眾提供了一個規(guī)范化的使用接口,無論這個接口是快速安全的支付平臺,還是一個簡單快捷的訂票網(wǎng)站。這種封裝和接口的思維反映在社會生活的很多方面。因此,學(xué)習(xí)編程也是理解當(dāng)代生活的一個必要步驟。1.3為什么學(xué)Python正如1.2節(jié)所說,高級語言的關(guān)鍵是封裝,讓程序編寫變得簡單。Python正是因為在這一點上做得優(yōu)秀,才成為主流編程語言之一。Python的使用相當(dāng)廣泛,是Google的第三大開發(fā)語言,也是Dropbox、Quora、Pinterest、豆瓣等網(wǎng)站主要使用的語言。在很多科研領(lǐng)域,如數(shù)學(xué)、人工智能、生物信息、天體物理等,Python都應(yīng)用廣泛,漸有一統(tǒng)天下的勢頭。當(dāng)然,Python的成功并非一蹴而就。它從誕生開始,已經(jīng)經(jīng)歷了二三十年的發(fā)展?;仡橮ython的歷史,我們不但可以了解Python的發(fā)展歷程,還能理解Python的哲學(xué)和理念。Python的作者是吉多·范·羅蘇姆(GuidovonRossum)。羅蘇姆是荷蘭人。1982年,他從阿姆斯特丹大學(xué)(UniversityofAmsterdam)獲得了數(shù)學(xué)和計算機碩士學(xué)位。然而,盡管他算得上是一位數(shù)學(xué)家,但他更加享受計算機帶來的樂趣。用他的話說,盡管擁有數(shù)學(xué)和計算機雙料資質(zhì),但他總是趨向于做計算機相關(guān)的工作,并熱衷于做任何和編程相關(guān)的活兒。在編寫Python之前,羅蘇姆接觸并使用過諸如Pascal、C、Fortran等語言。這些語言的關(guān)注點是讓程序更快運行。在20世紀(jì)80年代,雖然IBM和蘋果已經(jīng)掀起了個人電腦浪潮,但這些個人電腦的配置在今天看來十分低下。早期的蘋果電腦只有8MHz的CPU主頻和128KB的內(nèi)存,稍微復(fù)雜一點的運算就能讓電腦死機。因此,當(dāng)時編程的核心是優(yōu)化,讓程序能夠在有限的硬件性能下順利運行。為了增進(jìn)效率,程序員不得不像計算機一樣思考,以便能寫出更符合機器口味的程序。他們恨不得用手榨取計算機的每一寸能力。有人甚至認(rèn)為C語言的指針是在浪費內(nèi)存。至于我們現(xiàn)在編程經(jīng)常使用的高級特征,如動態(tài)類型、內(nèi)存自動管理、面向?qū)ο蟮?,在那個時代只會讓電腦陷入癱瘓。然而,以性能為唯一關(guān)注點的編程方式讓羅蘇姆感到苦惱。即使他在腦子中清楚知道如何用C語言來實現(xiàn)一個功能,但整個編寫過程仍然需要耗費大量的時間。相對于C語言,羅蘇姆更喜歡Shell實現(xiàn)功能的方式。UNIX系統(tǒng)的管理員們常常用Shell去寫一些簡單的腳本,以進(jìn)行一些系統(tǒng)維護的工作,比如定期備份、文件系統(tǒng)管理,等等。Shell可以像膠水一樣,將UNIX下的許多功能連接在一起。許多C語言下數(shù)百行的程序,在Shell下只用幾行就可以完成。然而,Shell的本質(zhì)是調(diào)用命令,它并不是一個真正的語言。比如說,Shell數(shù)據(jù)類型單一、運算復(fù)雜等。總之,Shell不是一個合格的通用程序語言。羅蘇姆希望有一種通用程序語言,既能像C語言那樣調(diào)用計算機所有的功能接口,又能像Shell那樣輕松地編程。最早讓羅蘇姆看到希望的是ABC語言。ABC語言是由荷蘭的數(shù)學(xué)和計算機研究所(CentrumWiskunde&Informatica)開發(fā)的。這家研究所是羅蘇姆上班的地方,因此羅蘇姆正好能參與ABC語言的開發(fā)。ABC語言以教學(xué)為目的。與當(dāng)時的大部分語言不同,ABC語言的目標(biāo)是“讓用戶感覺更好”。ABC語言希望讓語言變得容易閱讀、容易使用、容易記憶和容易學(xué)習(xí),以此來激發(fā)人們學(xué)習(xí)編程的興趣。比如,下面是一段來自維基百科的ABC程序,這個程序用于統(tǒng)計文本中出現(xiàn)的詞的總數(shù):
HOWTORETURNwordsdocument:
PUT{}INcollection
FORlineINdocument:
FORwordINsplitline:
IFwordnot.incollection:
INSERTwordINcollection
RETURNcollection
HOWTO用于定義一個函數(shù),ABC語言使用冒號和縮進(jìn)來表示程序塊\h\h(1),行尾沒有分號,for和if結(jié)構(gòu)中沒有括號。上面的程序讀起來就像一段自然的文字。盡管已經(jīng)具備了良好的可讀性和易用性,但ABC語言并未流行起來。在當(dāng)時,ABC語言編譯器需要比較高配置的電腦才能運行。在那個時代,高配置電腦是稀罕物,其使用者往往精通計算機。這些人更在意程序的效率,而非語言的學(xué)習(xí)難度。除了性能,ABC語言的設(shè)計還存在一些致命的問題:可拓展性差。ABC語言不是模塊化語言。如果想在ABC語言中增加功能,比如對圖形化的支持,就必須改動很多地方。不能直接進(jìn)行輸入輸出。ABC語言不能直接操縱文件系統(tǒng)。盡管你可以通過諸如文本流的方式導(dǎo)入數(shù)據(jù),但ABC語言無法直接讀寫文件。輸入輸出的困難對于計算機語言來說是致命的。你能想像一個打不開車門的跑車么?過度革新。ABC語言用自然語言的方式來表達(dá)程序的含義,比如上面程序中的HOWTO(如何)。然而對于掌握了多種語言的程序員來說,他們更習(xí)慣用function或者define來定義一個函數(shù)。同樣,程序員也習(xí)慣了用等號(=)來分配變量。革新盡管讓ABC語言顯得特別,但實際上增加了程序員的學(xué)習(xí)難度。傳播困難。ABC編譯器很大,必須被保存在磁帶(tape)上。羅蘇姆在學(xué)術(shù)交流時,就必須用一個大磁帶來給別人安裝ABC編譯器。這使得ABC語言很難快速傳播。1989年,為了打發(fā)圣誕節(jié)假期,羅蘇姆開始寫Python語言的編譯/解釋器。Python這個詞在英文中的意思是蟒蛇。但羅蘇姆選擇這個名字的原因與蟒蛇無關(guān),而是來源于他摯愛的一部電視劇\h\h(2)。他希望這個新的叫作Python的語言,能實現(xiàn)他的理念。也就是一種在C和Shell之間,功能全面、易學(xué)易用、可拓展的語言。羅蘇姆作為一名語言設(shè)計愛好者,已經(jīng)有過設(shè)計語言的的嘗試。雖然上次的語言設(shè)計并不成功,但羅蘇姆依然樂在其中。這一次設(shè)計Python語言,也不過是他又一次尋找樂趣的小創(chuàng)造。1991年,第一個Python編譯/解釋器誕生。它是用C語言實現(xiàn)的,能夠調(diào)用C語言生成的動態(tài)鏈接庫\h\h(3)。從一出生,Python就已經(jīng)具有了一直保持到現(xiàn)在的基本語法:類(class)、函數(shù)(function)、異常處理(exception)、包括表(list)和詞典(dictionary)在內(nèi)的核心數(shù)據(jù)類型,以及模塊(module)為基礎(chǔ)的拓展系統(tǒng)。圖1-3最初的Python圖標(biāo)Python語法很多來自C,但又受到ABC語言的強烈影響。Python像ABC語言一樣,比如用縮進(jìn)代替花括號,從而保證程序更易讀(readability)。羅蘇姆認(rèn)為,程序員讀代碼的時間要遠(yuǎn)遠(yuǎn)多于寫代碼的時間。強制縮進(jìn)能讓代碼更清晰易讀,應(yīng)該予以保留。但與ABC語言不同的是,羅蘇姆同樣重視實用性(practicality)。在保證易讀性的前提下,Python會乖巧地服從其他語言中已有的一些語法慣例。Python用等號賦值,與多數(shù)語言保持一致。它使用def來定義函數(shù),而不是像ABC語言那樣使用生僻的HOWTO。羅蘇姆認(rèn)為,如果是“常識”上已確立的東西,就沒有必要過度創(chuàng)新。Python還特別在意可拓展性(extensibility),這是羅蘇姆實用主義原則的又一體現(xiàn)。Python可以在多個層次上拓展。從高層上,你可以引入其他人編寫的Python文件,來為自己的代碼拓展功能。如果出于性能考慮,你還可以直接引入C和C++語言編譯出的庫。由于C和C++語言在代碼方面的多年儲備,Python相當(dāng)于站在了巨人的肩膀上。Python就像是使用鋼構(gòu)建房一樣,先規(guī)定好大的框架,再借著模塊系統(tǒng)給程序員以自由發(fā)揮的空間。最初的Python完全由羅蘇姆本人開發(fā)。由于Python隱藏了許多機器層面上的細(xì)節(jié),并凸顯出了邏輯層面的編程思考,所以這個好用的語言得到了羅蘇姆同事的歡迎。同事們在工作中樂于使用Python,然后向羅蘇姆反饋使用意見,其中不少人都參與到語言的改進(jìn)。羅蘇姆和他的同事構(gòu)成了Python的核心團隊,他們將自己大部分的業(yè)余時間都奉獻(xiàn)給了Python。Python也逐漸從羅蘇姆的同事圈傳播到其他科研機構(gòu),慢慢用于學(xué)術(shù)圈之外的程序開發(fā)。Python的流行與計算機性能的大幅提高密不可分。20世紀(jì)90年代初,個人計算機開始進(jìn)入普通家庭。英特爾發(fā)布了486處理器,成為第四代處理器的代表。1993年,英特爾又推出了性能更好的奔騰處理器。計算機的性能大大提高。程序員不必再費盡心力提高程序效率,開始越來越關(guān)注計算機的易用性。微軟發(fā)布Windows3.0開始的一系列視窗系統(tǒng),用方便的圖形化界面吸引了大批普通用戶。那些能快速生產(chǎn)出軟件的語言成為新的明星,比如運行在虛擬機上的Java。Java完全基于面向?qū)ο蟮木幊谭妒?,能在犧牲性能的代價下,提高程序的產(chǎn)量。Python的步伐落后于Java,但它的易用性同樣符合時代潮流。前面說過,ABC語言失敗的一個重要原因是硬件的性能限制。從這方面來說,Python要比ABC語言幸運許多。另一個悄然發(fā)生的改變是互聯(lián)網(wǎng)。20世紀(jì)90年代還是個人電腦的時代,微軟和英特爾挾PC以令天下,幾乎壟斷了個人電腦市場。當(dāng)時,大眾化的信息革命尚未到來,但對于近水樓臺的程序員來說,互聯(lián)網(wǎng)已經(jīng)是平日里常用的工具。程序員率先使用互聯(lián)網(wǎng)進(jìn)行交流,如電子郵件和新聞組。互聯(lián)網(wǎng)讓信息交流成本大大降低,也讓有共同愛好的人能夠跨越地理限制聚合起來。以互聯(lián)網(wǎng)的通信能力為基礎(chǔ),開源(OpenSource)的軟件開發(fā)模式變得流行。程序員利用業(yè)余時間進(jìn)行軟件開發(fā),并開放源代碼。1991年,林納斯·托瓦茲在comp.os.minix新聞組上發(fā)布了Linux內(nèi)核源代碼,吸引了大批程序員加入開發(fā)工作,引領(lǐng)了開源運動的潮流。Linux和GNU相互合作,最終構(gòu)成了一個充滿活力的開源平臺。羅蘇姆本人也是一位開源先鋒,他維護了一個郵件列表,并把早期的Python用戶都放在里面。早期Python用戶就可以通過郵件進(jìn)行群組交流。這些用戶大多都是程序員,有相當(dāng)優(yōu)秀的開發(fā)能力。他們來自許多領(lǐng)域,有不同的背景,對Python也提出了各種各樣的功能需求。由于Python相當(dāng)開放,又容易拓展,所以當(dāng)一個人不滿足于現(xiàn)有功能時,他很容易對Python進(jìn)行拓展或改造。隨后,這些用戶將改動發(fā)給羅蘇姆,由他決定是否將新的特征加入到Python中\(zhòng)h\h(4)。如果代碼能被采納,將會是極大的榮譽。羅蘇姆本人的角色越來越偏重于框架的制定。如果問題太復(fù)雜,則羅蘇姆會選擇繞過去,也就是走捷徑(cutthecorner),把其留給社區(qū)的其他人解決。就連創(chuàng)建網(wǎng)站\h\h(5)、籌集基金\h\h(6)這樣的事情,也有人樂于處理。社區(qū)日漸成熟,開發(fā)工作被整個社區(qū)分擔(dān)。Python的一個理念是自帶電池(BatteryIncluded)。也就是說,Python已經(jīng)有了功能豐富的模塊。所謂模塊,就是別人已經(jīng)編寫好的Python程序,能實現(xiàn)一定的功能。一個程序員在編程時不需要重復(fù)造輪子,只需引用已有的模塊即可。這些模塊既包括Python自帶的標(biāo)準(zhǔn)庫,也包括了標(biāo)準(zhǔn)庫之外的第三方庫。這些“電池”同樣是整個社區(qū)的貢獻(xiàn)。Python的開發(fā)者來自于不同領(lǐng)域,他們將不同領(lǐng)域的優(yōu)點帶給Python。Python標(biāo)準(zhǔn)庫中的正則表達(dá)(regularexpression)參考了Perl,函數(shù)式編程的相關(guān)語法則參考了Lisp語言,兩者都來自于社區(qū)的貢獻(xiàn)。Python在簡明的語法框架下,提供了豐富的武器庫。無論是建立一個網(wǎng)站,制作一個人工智能程序,還是操縱一個可穿戴設(shè)備,都可以借助已有的庫再加上簡短的代碼實現(xiàn)。這恐怕是Python程序員最幸福的地方了。當(dāng)然,Python也有讓人痛苦的地方。Python當(dāng)前最新的版本是3,但Python3與Python2不兼容。由于很多現(xiàn)存的代碼是Python2編寫的,所以從版本2到版本3的過渡并不容易。許多人選擇了繼續(xù)使用Python2。有人開玩笑說,Python2的版本號會在未來增加到2.7.31415926。除了版本選擇上的問題,Python的性能也不時被人詬病。Python的運算性能低于C和C++,我們會在本書中提及其原因。盡管Python也在提高自身的性能,但性能的差距會一直存在。不過從Python的發(fā)展歷史來看,類似的批判其實是吹毛求疵。Python本身就是用性能來交換易用性,走的就是和C、C++相反的方向。說一個足球前鋒的守門技術(shù)不好,并沒有太大的意義。對于初學(xué)編程的人來說,從Python開始學(xué)習(xí)編程的好處很多,如上面已經(jīng)提到的語法簡單和模塊豐富。國外許多大學(xué)的計算機導(dǎo)論課程,都開始選擇Python作為課程語言,替代了過去常用的C或Java。但如果把Python當(dāng)作所謂的“最好的語言”,希望學(xué)一門Python就成為“萬人敵”,則是一種幻想。每個語言都有它優(yōu)秀的地方,但也有各種各樣的缺陷。一個語言“好與不好”的評判,還受制于平臺、硬件、時代等外部原因。更進(jìn)一步,很多開發(fā)工作需要特定的語言,比如用Java來編寫安卓應(yīng)用,用Objective-C或Swift來編寫蘋果應(yīng)用。無論從哪一門語言學(xué)起,最終都不會拘泥于初學(xué)的那門語言。只有博彩眾家,才能讓編程的創(chuàng)造力自由發(fā)揮。1.4最簡單的HelloWorldPython的安裝很方便,可以參考本章的附錄A。運行Python的方式有兩種。如果你想嘗試少量程序,并立即看到結(jié)果,則可以通過命令行(CommandLine)來運行Python。所謂的命令行,就是一個等著你用鍵盤來打字的小輸入欄,可以直接與Python對話。按照附錄A的方法啟動命令行,就進(jìn)入了Python。通常來說,命令行都會有>>>字樣的提示符,提醒你在提示符后面輸入。你輸入的Python語句會被Python的解釋器(interpreter)\h\h(7)轉(zhuǎn)化成計算機指令。我們現(xiàn)在執(zhí)行一個簡單的操作:讓計算機屏幕顯示出一行字。在命令行提示符后面輸入下列文字,并按鍵盤上的回車鍵(Enter)確認(rèn):
>>>print("HelloWorld!")
可以看到,屏幕上會隨后顯示:
HelloWorld!
輸入的print是一個函數(shù)的名稱。函數(shù)有特定的功能,print()函數(shù)的功能就是在屏幕上打印出字符。函數(shù)后面有一個括號,里面說明了想要打印的字符是"HelloWorld!"。括號里的一對雙引號并沒有打印在屏幕上。這一對雙引號的作用是從print之類的程序文本中出標(biāo)記出普通字符,以免計算機混淆。也可以用一對單引號替換雙引號。使用Python的第二種方式是寫一個程序文件(ProgramFile)。Python的程序文件以.py為后綴,它可以用任何文本編輯器來創(chuàng)建和編寫。附錄A中說明了不同操作系統(tǒng)下常用的文本編輯器。創(chuàng)建文件hello.py,寫入如下內(nèi)容,并保存:
print("HelloWorld!")
可以看到,這里的程序內(nèi)容和用命令行時一模一樣。與命令行相比,程序文件適用于編寫和保存量比較大的程序。運行程序文件hello.py,可以看到Python同樣在屏幕上打印出了HelloWorld!。程序文件的內(nèi)容和命令行里敲入的內(nèi)容一模一樣,產(chǎn)生的效果也一樣。與命令行直接輸入程序相比,程序文件更容易保存和更改,所以常用于編寫大量程序。程序文件的另一個好處是可以加入注釋(comments)。注釋是一些文字,用來解釋某一段程序,也方便其他程序員了解這段程序。所以,注釋的內(nèi)容并不會被當(dāng)作程序執(zhí)行。在Python的程序文件中,每一行中從#開始的文字都是注釋,我們可以給hello.py加注釋:
print("HelloWorld!")#displaytextonthescreen
如果注釋的內(nèi)容較多,在一行里面放不下,那么可以用多行注釋(multilinecomments)的方法:
"""
Author:Vamei
Function:displaytextonthescreen
"""
print('HelloWorld!')
多行注釋的標(biāo)志符是三個連續(xù)的雙引號。多行注釋也可以使用三個連續(xù)的單引號。兩組引號之間的內(nèi)容,就是多行注釋的內(nèi)容。無論是想要打印的字符,還是用于注釋的文字,都可以是中文。如果在Python2中使用中文,則需要在程序開始之前加上一行編碼信息,以說明程序文件中使用了支持中文的utf-8編碼。在Python3中不需要這一行信息。
#-
*
-coding:utf-8-
*
-
print("你好,世界!")#在屏幕上顯示文字
就這樣,我們寫出了一個非常簡單的Python程序。不要小看了這個程序。在實現(xiàn)這個程序的過程中,你的計算機進(jìn)行了復(fù)雜的工作。它讀取了程序文件,在內(nèi)存中分配了空間,進(jìn)行了許多運算和控制,最終才控制屏幕的顯像原件,讓它顯示出一串字符。這個程序的順利運行,說明計算機硬件、操作系統(tǒng)和語言編譯器都已經(jīng)安裝并設(shè)置好。因此,程序員編程的第一個任務(wù),通常都是在屏幕上打印出HelloWorld\h\h(8)。第一次遇見Python的世界,就用HelloWorld和它打聲招呼吧。附錄APython的安裝與運行1.官方版本安裝1)MacMac系統(tǒng)上已經(jīng)預(yù)裝了Python,可以直接使用。如果想要使用其他版本的Python,建議使用Homebrew安裝\h\h(9)。打開終端(Terminal),在命令行提示符后輸入下面命令后,將進(jìn)入Python的可以互動的命令行:
$python
上面輸入的python通常是一個軟鏈接,指向某個版本的Python命令,如3.5版本。如果相應(yīng)版本已經(jīng)安裝,那么可以用下面的方式來運行:
$python3.5
終端會出現(xiàn)Python的相關(guān)信息,如Python的版本號,然后就會出現(xiàn)Python的命令行提示符>>>。如果想要退出Python,則輸入:
>>>exit()
如果想要運行當(dāng)前目錄下的某個Python程序文件,那么在python或python3后面加上文件的名字:
$pythonhello.py
如果文件不在當(dāng)前目錄下,那么需要說明文件的完整路徑,如
$python/home/vamei/hello.py
我們還可以把Python程序hello.py改成一個可執(zhí)行的腳本。只需在hello.py的第一行加上所要使用的Python解釋器:
#!/usr/bin/envpython
在終端中,把hello.py的權(quán)限改為可執(zhí)行:
$chmod755hello.py
然后在命令行中,輸入程序文件的名字,就可以直接使用規(guī)定的解釋器運行了:
$./hello.py
如果hello.py在默認(rèn)路徑下,那么系統(tǒng)就可以自動搜索到這個可執(zhí)行文件,就可以在任何路徑下運行這個文件了:
$hello.py
2)Linux操作系統(tǒng)Linux系統(tǒng)與Mac系統(tǒng)比較類似,大多也預(yù)裝了Python。很多Linux系統(tǒng)下都提供了類似于Homebrew的軟件管理器,例如在Ubuntu下使用下面命令安裝:
$sudoapt-getinstallpython
在Linux下,Python的使用和運行方式也和Mac系統(tǒng)下類似,這里不再贅述。3)Windows操作系統(tǒng)對于Windows操作系統(tǒng)來說,需要到Python的官方網(wǎng)站\h\h(10)下載安裝包。如果無法訪問Python的官網(wǎng),那么可以通過搜索引擎查找“pythonWindows下載”這樣的關(guān)鍵字,來尋找其他的下載源。安裝過程與安裝其他Windows軟件類似。在安裝界面中,選擇Customize來個性化安裝,除了選擇Python的各個組件外,還要勾選:
Addpython.exetoPath
安裝好之后,就可以打開Windows的命令行,像在Mac中一樣使用Python了。2.其他Python版本官方版本的Python主要提供了編譯/解釋器功能。其他一些非官方版本則有更加豐富的功能和界面,比如更加友好的圖形化界面、一個針對Python的文本編輯器,或者是一個更容易使用的模塊管理系統(tǒng),方便你找到各種拓展模塊等。在非官方的Python中,最常用的有下面兩個:1)Anaconda\h\h(11)2)EnthoughtPythonDistribution(EPD)\h\h(12)相對于官方版本的Python來說,這兩個版本都更容易安裝和使用。在模塊管理系統(tǒng)的幫助下,程序員還可以避免模塊安裝方面的惱人問題。所以非常推薦初學(xué)者使用。Anaconda是免費的,EPD則對于學(xué)生和科研人員免費。由于提供了圖形化界面,因此它們的使用方法也相當(dāng)直觀。我強烈建議初學(xué)者從這兩個版本中挑選一個使用。具體用法可以參考官方文檔,這里不再贅述。附錄Bvirtualenv一臺計算機中可以安裝多個版本的Python,而使用virtualenv則可給每個版本的Python創(chuàng)造一個虛擬環(huán)境。下面就使用Python附帶的pip\h\h(13)來安裝virtualenv:
$pipinstallvirtualenv
你可以為計算機中某個版本的Python創(chuàng)建一個虛擬空間,比如:
$virtualenv–p/usr/bin/python3.5myenv
上面的命令中,/usr/bin/python3.5是解釋器所在的位置,myenv是新建的虛擬環(huán)境的名稱。下面命令可開始使用myenv這個虛擬環(huán)境:
$sourcemyenv/bin/activate
使用下面命令可退出虛擬環(huán)境:
$deactivate
————————————————————\h(1)很多語言使用{}來表示程序塊,比如C、Java和JavaScript。\h(2)這部電視劇是《蒙提·派森的飛行馬戲團》(MontyPython'sFlyingCircus)。這部英國喜劇在當(dāng)時廣受歡迎。蒙提·派森是主創(chuàng)劇團的名字。Python即來自這里的“派森”。\h(3)即.so文件。\h(4)羅蘇姆充當(dāng)了社區(qū)的決策者。因此,他被稱為仁慈的獨裁者(BenevolentDictatorForLife)。在Python早期,不少Python追隨者擔(dān)心羅蘇姆的生命。他們甚至熱情討論:如果羅蘇姆出了車禍,Python會怎樣。\h(5)\h(6)PythonSoftwareFoundation\h(7)Python的解釋器是一個運行著的程序。它可以把Python語句一行一行地直接轉(zhuǎn)譯運行。\h(8)HelloWorld!之所以流行,是因為它被經(jīng)典編程教材《C程序設(shè)計語言》用作例子。\h(9)Homebrew是Mac下的軟件包管理工具,其官方網(wǎng)址為:http://brew.sh/。\h(10)Python官網(wǎng):。\h(11)Anaconda官網(wǎng):www.continuum.io。\h(12)EPD官網(wǎng):/products/epd/。\h(13)將在第3章的附錄部分進(jìn)一步講解pip的使用。第2章先做鍵盤俠2.1計算機會算術(shù)2.2計算機記性好2.3計算機懂選擇2.4計算機能循環(huán)附錄A小練習(xí)附錄B代碼規(guī)范本章將講述運算、變量、選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。常見的高級語言都提供這些語法。利用這些語法,我們也能利用計算機實現(xiàn)一些小型的程序,從而讓編程立即應(yīng)用于生活。例如,平時做數(shù)學(xué)運算,可以習(xí)慣性地用Python的命令行做計算器。敲幾行程序,實現(xiàn)一個小功能,就已經(jīng)能讓人享受編程的樂趣了。2.1計算機會算術(shù)1.?dāng)?shù)值運算既然名為“計算機”,那么數(shù)學(xué)計算自然是計算機的基本功。Python中的運算功能簡單且符合直覺。打開Python命令行,輸入如下的數(shù)值運算,立刻就能進(jìn)行運算:
>>>1+9#加法。結(jié)果為10
>>>1.3–4#減法。結(jié)果為-2.7
>>>3
*
5#乘法。結(jié)果為15
>>>4.5/1.5#除法。結(jié)果為3.0
>>>3
**
2#乘方,即求3的二次方。結(jié)果為9
>>>10%3#求余數(shù),就求10除以3的余數(shù)。結(jié)果為1
有了這些基礎(chǔ)運算后,我們就可以像用一個計算器一樣使用Python。以買房為例。一套房產(chǎn)的價格為86萬元,購買時需要付15%的稅,此外還要向銀行支付20%的首付。那么我們可以用下面代碼計算出需要準(zhǔn)備的現(xiàn)金:
>>>860000
*
(0.15+0.2)#結(jié)果為301000.0,即30萬1千元
除了常見的數(shù)值運算,字符串也能進(jìn)行加法運算。其效果是把兩個字符串連成一個字符串:
>>>"Vameisay:"+"HelloWorld"#連接成"Vameisay:HelloWorld!"
一個字符串還能和一個整數(shù)進(jìn)行乘法運算:
>>>"Vamei"
*
2#結(jié)果為"VameiVamei"
一個字符串與一個整數(shù)n相乘的話,會把該字符串重復(fù)n次。2.邏輯運算除了進(jìn)行數(shù)值運算外,計算機還能進(jìn)行邏輯運算。如果玩過殺人游戲,或者喜歡偵探小說,那么就很容易理解邏輯。就好像偵探福爾摩斯一樣,我們用邏輯去判斷一個說法的真假。一個假設(shè)性的說法被稱為命題,比如說“玩家甲是殺手”。邏輯的任務(wù)就是找出命題的真假。第1章中已經(jīng)提到,計算機采用了二進(jìn)制,即用0和1來記錄數(shù)據(jù)。計算機之所以采用二進(jìn)制,是有技術(shù)上的原因。許多組成計算機的原件,都只能表達(dá)兩個狀態(tài),比如電路的開和關(guān)、或者電壓的高和低。這樣造出的系統(tǒng)也相對穩(wěn)定。如果使用十進(jìn)制,那么某些計算機原件就要有10個狀態(tài),比如把電壓分成十個檔。那樣的話,系統(tǒng)就會變得復(fù)雜且容易出錯。在二進(jìn)制體系下,可以用1和0來代表“真”和“假”兩種狀態(tài)。在Python中,我們使用True和False兩個關(guān)鍵字來表示真假。True和False這樣的數(shù)據(jù)被稱為布爾值(Boolean)。有的時候,我們需要進(jìn)一步的邏輯運算,從而判斷復(fù)雜命題的真假。比如第一輪時我知道了“玩家甲不是殺手”為真,第二輪我知道了“玩家乙不是殺手”也是真。那么在第三輪時,如果有人說“玩家甲不是殺手,而且玩家乙也不是殺手”,那么這個人就是在說真話。用“而且”連接起來的兩個命題分別為真,那么整體命題就是真。無形中,我們進(jìn)行了一次“與”的邏輯運算。在“與”運算中,兩個子命題必須都為真時,用“與”連接起來的復(fù)合命題才是真?!芭c”運算就像是接連的兩座橋,必須兩座橋都通暢,才能過河,如圖2-1所示。以“中國在亞洲,而且英國也在亞洲”這個命題為例?!坝趤喼蕖边@個命題是假的,所以整個命題就是假的。在Python中,我們用and來表示“與”的邏輯運算。
>>>TrueandTrue#結(jié)果為True
>>>FalseandTrue#結(jié)果為False
>>>FalseandFalse#結(jié)果為False
圖2-1“與”和“或”運算我們還可以用“或者”把兩個命題復(fù)合在一起。與咄咄逼人的“而且”關(guān)系相比,“或者”顯得更加謙遜。比如在“中國在亞洲,或者英國在亞洲”這個說法中,說話的人就給自己留了余地。由于這句話的前一半是對的,所以整個命題就是真的?!盎蛘摺本蛯?yīng)了“或”邏輯運算。在“或”運算中,只要有一個命題為真,那么用“或”連接起來的復(fù)合命題就是真?!盎颉边\算就像并行跨過河的兩座橋,任意一座通暢,就能讓行人過河。Python用or來進(jìn)行“或”的邏輯運算。
>>>TrueorTrue#結(jié)果為True
>>>TrueorFalse#結(jié)果為True
>>>FalseorFalse#結(jié)果為False
最后,還有一種稱為非的邏輯運算,其實就是對一個命題求反。比如“甲不是殺手”為真,那么“甲是殺手”這個反命題就是假。Python使用not這個關(guān)鍵字來表示非運算,比如:
>>>notTrue#結(jié)果為False
3.判斷表達(dá)式上面的邏輯運算看起來似乎只是些生活經(jīng)驗,完全不需要計算機這樣的復(fù)雜工具。加入判斷表達(dá)式之后,邏輯運算方能真正顯示出它的威力。判斷表達(dá)式其實就是用數(shù)學(xué)形式寫出來的命題。比如“1等于1”,寫在Python里就是:
>>>1==1#結(jié)果為True
符號==表示了相等的關(guān)系。此外,還有其他的判斷運算符:
>>>8.0!=8.0#!=,不等于
>>>4<5#<,小于
>>>3<=3#<=,小于或等于
>>>4>5#>,大于
>>>4>=0#>=,大于等于
這些判斷表達(dá)式都很簡單。即使不借助Python,也能很快在頭腦中得出它們的真假。但如果把數(shù)值運算、邏輯運算和判斷表達(dá)式放在一起,就能體現(xiàn)出計算機的優(yōu)勢了。還是用房貸的例子,房產(chǎn)價格86萬元,稅率15%,首付20%。假如我手里有40萬元的現(xiàn)金。出于稅務(wù)原因,我還希望自己付的稅款低于13萬元,那么是否還可以買這套房子?這個問題可以借用Python進(jìn)行計算。
>>>860000
*
(0.15+0.2)<=400000and860000
*
0.15<130000
答案是True,可以買房!4.運算優(yōu)先級如果一個表達(dá)式中出現(xiàn)多個運算符,就要考慮運算優(yōu)先級的問題。不同的運算符號優(yōu)先級不同。運算符可以按照優(yōu)先級先后歸為:
乘方:
**
乘除:
*
/
加減:+-
判斷:==>>=<<=
邏輯:!andor
如果是相同優(yōu)先級的運算符,那么Python會按照從左向右的順序進(jìn)行運算,比如:
>>>4+2-1#先執(zhí)行加法,再執(zhí)行減法。結(jié)果為5
如果有優(yōu)先級高的運算符,Python會打破從左向右的默認(rèn)次序,先執(zhí)行優(yōu)先級高的運算,比如:
>>>4+2
*
2#先執(zhí)行乘法,再執(zhí)行加法。結(jié)果為8
括號會打破運算優(yōu)先級。如果有括號存在,會先進(jìn)行括號中的運算:
>>>(4+2)
*
2#先執(zhí)行加法,再執(zhí)行乘法。結(jié)果為12
2.2計算機記性好1.變量革命上面的運算中出現(xiàn)的數(shù)據(jù),無論是1和5.2這樣的數(shù)值,還是True和False這樣的布爾值,都會在運算結(jié)束后消失。有時,我們想把數(shù)據(jù)存儲到存儲器中,以便在后面的程序中重復(fù)使用。計算機存儲器中的每個存儲單元都有一個地址,就像是門牌號。我們可以把數(shù)據(jù)存入特定門牌號的隔間,然后通過門牌號來提取之前存儲的數(shù)據(jù)。但用內(nèi)存地址來為存儲的地址建索引,其實并不方便:內(nèi)存地址相當(dāng)冗長,難以記憶。每個地址對應(yīng)的存儲空間大小固定,難以適應(yīng)類型多變的數(shù)據(jù)。對某個地址進(jìn)行操作前,并不知道該地址的存儲空間是否已經(jīng)被占用。隨著編程語言的發(fā)展,開始有了用變量的方式來存儲數(shù)據(jù)。變量和內(nèi)存地址類似,也起到了索引數(shù)據(jù)的功能。新建變量時,計算機在空閑的內(nèi)存中開辟存儲空間,用來存儲數(shù)據(jù)。和內(nèi)存地址不同的是,根據(jù)變量的類型,分配的存儲空間會有大小變化。程序員給變量起一個變量名,在程序中作為該變量空間的索引。數(shù)據(jù)交給變量,然后在需要的時候通過變量的名字來提取數(shù)據(jù)。比如下面的Python程序:
v="Vivian"
print(v)#打印出"Vivian"
在上面的程序中,我們把數(shù)值10交給變量v保存,這個過程稱為賦值(Assignment)。Python中用等號=來表示賦值。借助賦值,一個變量就建立了。從硬件的角度來看,給變量賦值的過程,就是把數(shù)據(jù)存入內(nèi)存的過程。變量就像能裝數(shù)據(jù)的小房間,變量名是門牌號。賦值操作是讓某個客人前往該房間?!白孷ivian入住到v字號房?!痹陔S后的加法運算中,我們通過變量名v取出了變量所包含的數(shù)據(jù),然后通過print()打印出來。變量名是從內(nèi)存中找到對應(yīng)數(shù)據(jù)的線索。有了存儲功能,計算機就不會犯“失憶癥”了?!皏字號房住的是誰?”“是Vivian呀。”酒店的房間會有不同的客人入住或離開。變量也是如此。我們可以給一個變量賦其他的值。這樣,房間里的客人就變了。
v="Tom"
print(v)#打印出"Tom"
在計算機編程時,經(jīng)常設(shè)置許多變量,讓每個變量存儲不同功能的數(shù)據(jù)。例如,電腦游戲中可能記錄玩家擁有的不同資源的數(shù)目,就可以用不同的變量記錄不同的資源。
gold=100#100個金子
wood=20#20個木材
wheat=29#29個小麥
在游戲過程中,可以根據(jù)情況增加或者減少某種資源。例如,玩家選擇伐木,就增加5個木材。這個時候,就可以對相應(yīng)變量執(zhí)行加5的操作。
wood=wood+5
print(wood)#打印出25
計算機先執(zhí)行賦值符號右邊的運算。原有的變量值加5,再賦予給同一個變量。在游戲進(jìn)行的整個過程中,變量wood起到了追蹤木材數(shù)據(jù)的作用。玩家的資源數(shù)據(jù)被妥善地存儲起來。變量名直接參與運算,這是邁向抽象思維的第一步。在數(shù)學(xué)上,用符號來代替數(shù)值的做法稱為代數(shù)。今天的很多中學(xué)生都會列出代數(shù)方程,來解決“雞兔同籠”之類的數(shù)學(xué)問題。但在古代,代數(shù)是相當(dāng)先進(jìn)的數(shù)學(xué)。歐洲人從阿拉伯人那里學(xué)到了先進(jìn)的代數(shù),利用代數(shù)的符號系統(tǒng),擺脫了具體數(shù)值的桎梏,更加專注于邏輯和符號之間的關(guān)系。在代數(shù)的基礎(chǔ)上發(fā)展出近代數(shù)學(xué),為近代的科技爆炸打下了基礎(chǔ)。變量也讓編程有了更高一層的抽象能力。變量提供的符號化表達(dá)方式,是實現(xiàn)代碼復(fù)用的第一步。比如之前計算購房所需現(xiàn)金的代碼:
860000
*
(0.15+0.2)
當(dāng)我們同時看多套房時,860000這個價格會不斷變動。為了方便,我們可以把程序?qū)懗桑?/p>
total=860000
requirement=total
*
(0.15+0.2)
print(requirement)#打印結(jié)果301000.0
這樣,每次在使用程序時,只需更改860000這個數(shù)值就可以了。當(dāng)然,我們還會在未來看到更多的復(fù)用代碼的方式。但變量這種用抽象符號代替具體數(shù)值的思維,具有代表性的意義。2.變量的類型數(shù)據(jù)可能有很多不同的類型,例如5這樣的整數(shù)、5.9這樣的浮點數(shù)、True和False這樣的布爾值,還有第1章中見過的字符串"HelloWorld!"。在Python中,我們可以把各種類型的數(shù)據(jù)賦予給同一個變量。比如:
var_integer=5
print(var_integer)#a存儲的內(nèi)容為整數(shù)5
var_string="HelloWorld!"
print(var_string)#a存儲的內(nèi)容變成字符串"HelloWorld!"
可以看到,后賦予給變量的值替換了變量原來的值。Python能自由改變變量類型的特征被稱為動態(tài)類型(DynamicTyping)。并不是所有的語言都支持動態(tài)類型。在靜態(tài)類型(StaticTyping)的語言中,變量有事先說明好的類型。特定類型的數(shù)據(jù)必須存入特定類型的變量。相比于靜態(tài)類型,動態(tài)類型顯得更加靈活便利。即使是可以自由改變,Python的變量本身還是有類型的。我們可以用type()這一函數(shù)來查看變量的類型。比如說:
var_integer=10
print(type(var_integer))
輸出結(jié)果是\h\h(1):
<class'int'>
int是整數(shù)integer的簡寫。除此之外,還會有浮點數(shù)(Float)、字符串(String,簡寫為str)、布爾值(Boolean,簡寫為bool)。常見的類型包括:
>>>a=100#整型
>>>a=100.0#浮點型
>>>a='abc'#字符串。也可以使用雙引號"abc"標(biāo)記字符串。
>>>a=True#布爾值
計算機需要用不同的方式來存儲不同的類型。整數(shù)可以直接用二進(jìn)制的數(shù)字表示,浮點數(shù)卻用額外記錄小數(shù)點的位置。每種數(shù)據(jù)所需的存儲空間也不同。計算機的存儲空間以位(bit)為單位,每一位能存儲一個0或1的數(shù)字。為了記錄一個布爾值,我們只需讓1代表真值,0代表假值就可以。所以布爾值的存儲只需要1位。對于整數(shù)4來說,變換成二進(jìn)制位100。為了存儲它,存儲空間至少要有3位,分別記錄1、0、0。為了效率和實用性,計算機在內(nèi)存中必須要分類型存儲。靜態(tài)類型語言中,新建變量必須說明類型,就是這個道理。動態(tài)類型的語言看起來不需要說明類型,但其實是把區(qū)分類型的工作交給解釋器。當(dāng)我們更改變量的值時,Python解釋器也在努力工作,自動分辨出新數(shù)據(jù)的類型,再為數(shù)據(jù)開辟相應(yīng)類型的內(nèi)存空間。Python解釋器貼心的服務(wù)讓編程更加方便,但也把計算機的一部分能力用于支持動態(tài)類型上。這也是Python的速度不如C語言等靜態(tài)類型語言的一個原因。3.序列Python中一些類型的變量,能像一個容器一樣,收納多個數(shù)據(jù)。本小節(jié)講的序列(Sequence)和下一小節(jié)的詞典(Dictionary),都是容器型變量。我們先從序列說起。就好像一列排好隊的士兵,序列是有順序的數(shù)據(jù)集合。序列包含的一個數(shù)據(jù)被稱為序列的一個元素(element)。序列可以包含一個或多個元素,也可以是完全沒有任何元素的空序列。序列有兩種,元組(Tuple)和列表(List)。兩者的主要區(qū)別在于,一旦建立,元組的各個元素不可再變更,而列表元素可以變更。所以,元組看起來就像一種特殊的表,有固定的數(shù)據(jù)。因此,有的翻譯也把元組稱為“定值表”。創(chuàng)建元組和表的方式如下:
>>>example_tuple=(2,1.3,"love",5.6,9,12,False)#一個元組
>>>example_list=[True,5,"smile"]#一個列表
>>>type(example_tuple)#結(jié)果為'tuple'
>>>type(example_list)#結(jié)果為'list'
可以看到,同一個序列可以包含不同類型的元素,這也是Python動態(tài)類型的一個體現(xiàn)。還有,序列的元素不僅可以是基本類型的數(shù)據(jù),還可以是另外一個序列。
>>>nest_list=[1,[3,4,5]]#列表中嵌套另一個列表
由于元組不能改變數(shù)據(jù),所以很少會建立一個空的元組。而序列可以增加和修改元素,所以Python程序中經(jīng)常會建立空表:
>>>empty_list=[]#空列表
既然序列也用于儲存數(shù)據(jù),那么我們不免要讀取序列中的數(shù)據(jù)。序列中的元素是有序排列,所以可以根據(jù)每個元素中的位置來找到對應(yīng)元素。序列元素的位置索引稱為下標(biāo)(Index)。Python中序列的下標(biāo)從0開始,即第一個元素的對應(yīng)下標(biāo)為0。這一規(guī)定有歷史原因在里面,是為了和經(jīng)典的C語言保持一致。我們嘗試引用序列中的元素:
>>>example_tuple[0]#結(jié)果為2
>>>example_list[2]#結(jié)果為'smile'
>>>nest_list[1][2]#結(jié)果為5
表的數(shù)據(jù)可變更,因此可以對單個元素進(jìn)行賦值。你可以通過下標(biāo),來說明想對哪個元素賦予怎樣的值:
>>>example_list[1]=3.0
>>>example_list#列表第二個元素變成3.0
元組一旦建立就不能改變,所以你不能對元組的元素進(jìn)行上面的賦值操作。對于序列來說,除了可以用下標(biāo)來找到單個元素外,還可以通過范圍引用的方式,來找到多個元素。范圍引用的基本樣式是:序列名[下限:上限:步長]下限表示起始下標(biāo),上限表示結(jié)尾下標(biāo)。在起始下標(biāo)和結(jié)尾下標(biāo)之間,按照步長的間隔來找到元素。默認(rèn)的步長為1,也就是下限和上限之間的每1個元素都會出現(xiàn)在結(jié)果中。引用的多個元素將成為一個新的序列。下面是一些范圍引用的例子。
>>>example_tuple[:5]#從小標(biāo)0到下標(biāo)4,不包括下標(biāo)5的元素
>>>example_tuple[2:]#從下標(biāo)2到最后一個元素
>>>example_tuple[0:5:2]#下標(biāo)為0,2,4的元素。
>>>sliced=example_tuple[2:0:-1]#從下標(biāo)2到下標(biāo)1
>>>type(sliced)#范圍引用的結(jié)果還是一個元組
上面都是用元組的例子,表的范圍引用效果完全相同。在范圍引用的時候,如果寫明上限,那么這個上限下標(biāo)指向的元素將不包括在結(jié)果中。此外,Python還提供了一種尾部引用的語法,用于引用序列尾部的元素:
>>>example_tuple[-1]#序列最后一個元素
>>>example_tuple[-3]#序列倒數(shù)第三個元素
>>>example_tuple[1:-1]#序列的第二個到倒數(shù)第二個元素
正如example_tuple[1:-1]這個例子,如果是范圍引用,那么上限元素將不包含在結(jié)果中。序列的好處是可以有序地儲存一組數(shù)據(jù)。一些數(shù)據(jù)本身就有有序性,比如銀行提供的房貸利率,每年都會上下浮動。這樣的一組數(shù)據(jù)就可以存儲在序列中:
interest_tuple=(0.01,0.02,0.03,0.035,0.05)
4.詞典詞典從很多方面都和表類似。它同樣是一個可以容納多個元素的容器。但詞典不是以位置來作為索引的。詞典允許用自定義的方式來建立數(shù)據(jù)的索引:
>>>example_dict={"tom":11,"sam":57,"lily":100}
>>>type(example_dict)#結(jié)果為'dict'
詞典包含有多個元素,每個元素以逗號分隔。詞典的元素包含兩部分,鍵(Key)和值(Value)。鍵是數(shù)據(jù)的索引,值是數(shù)據(jù)本身。鍵和值一一對應(yīng)。比如上面的例子中,"tom"對應(yīng)11,"sam"對應(yīng)57,"lily"對應(yīng)100。由于鍵值之間的一一對應(yīng)關(guān)系,所以詞典的元素可以通過鍵來引用。
>>>example_dict["tom"]#結(jié)果為11
在詞典中修改或增添一個元素的值:
>>>example_dict["tom"]=30
>>>example_dict["lilei"]=99
>>>example_dict#結(jié)果為{"tom":30,"lily":100,"lilei":99,"sam":57}
構(gòu)建一個新的空的詞典:
>>>example_dict={}
>>>example_dict#結(jié)果為{}
詞典不具備序列那樣的連續(xù)有序性,所以適于存儲結(jié)構(gòu)松散的一組數(shù)據(jù)。比如首付比例和稅率可以存在同一個詞典中:
rate={"premium":0.2,"tax":0.15}
在詞典的例子中,以及大部分的應(yīng)用場景中,我們都使用字符串來作為詞典的鍵。但其他類型的數(shù)據(jù),如數(shù)字和布爾值,也可以作為詞典的鍵值。本書將在后面講解,究竟哪些數(shù)據(jù)可以作為詞典的鍵值。2.3計算機懂選擇1.if結(jié)構(gòu)到現(xiàn)在為止,我們看到的Python程序都是指令式的。在程序中,計算機指令都按順序執(zhí)行。指令不能跳過,也不能回頭重復(fù)。最早的程序都是這個樣子。例如要讓燈光亮十次,就要重復(fù)寫十行讓燈亮的指令。為了讓程序能靈活,早期的編程語言加入了“跳轉(zhuǎn)”的功能。利用跳轉(zhuǎn)指令,我們就能在執(zhí)行過程中跳到程序中的任意一行指令繼續(xù)向下執(zhí)行。例如,想重復(fù)執(zhí)行,就跳到前面已經(jīng)執(zhí)行過的某一行。程序員為了方便,頻繁地在程序中向前或向后跳轉(zhuǎn)。結(jié)果,程序的運行順序看起來就像交纏在一起的面條,既難讀懂,又容易出錯。程序員漸漸發(fā)現(xiàn),其實跳轉(zhuǎn)最主要的功能,就是選擇性地執(zhí)行,或者重復(fù)執(zhí)行某段程序。計算機專家也論證出,只要有了“選擇”和“循環(huán)”兩種語法結(jié)果,“跳轉(zhuǎn)”就再無必要。兩種結(jié)構(gòu)都能改變程序執(zhí)行的流程,改變指令運行的次序。編程語言進(jìn)入到結(jié)構(gòu)化的時代。相對于“跳轉(zhuǎn)”帶來的“面條式程序”,結(jié)構(gòu)化的程序變得賞心悅目。在現(xiàn)代編程語言中,“跳轉(zhuǎn)”語法已經(jīng)被徹底廢除。我們先來看選擇結(jié)構(gòu)的一個簡單的例子。如果一個房子的售價超過50萬,那么交易費率為1%,否則為2%。我們用選擇結(jié)構(gòu)來寫一個程序。
total=980000
iftotal>500000:
transaction_rate=0.01
else:
transaction_rate=0.02
print(transaction_rate)#打印0.01
在這段程序中,出現(xiàn)了我們沒見過的if...else...語句。其實這個語句的功能一讀就懂。如果總價超過50萬,那么交易費率為1%;否則,交易費率為2%。關(guān)鍵字if和else分別有隸屬于它們的一行代碼,從屬代碼的開頭會有四個空格的縮進(jìn)。程序最終會根據(jù)if后的條件是否成立,選擇是執(zhí)行if的從屬代碼,還是執(zhí)行else的從屬代碼??傊?,if結(jié)構(gòu)在程序中實現(xiàn)了分支。if和else后面可以跟不止一行的程序:
total=980000
iftotal>500000:#該條件成立
print("總價超過50萬")#執(zhí)行這一句的打印
transaction_rate=0.01#設(shè)置費率為0.01
else:#else部分不執(zhí)行
print("總價不超過50萬")
transaction_rate=0.02
print(transaction_rate)#結(jié)果為0.01
可以看到,同屬于if或else的代碼有四個空格的縮進(jìn)。關(guān)鍵詞if和else就像兩個老大,站在行首。老大身旁還有靠后站的小弟。老大只有借著條件贏了,站在其身后的小弟才有機會亮相。最后一行print語句也站在行首,說明它和if、else兩位老大平起平坐,不存在隸屬關(guān)系。程序不需要條件判斷,總會執(zhí)行這一句。else也并非必需的,我們可以寫只有if的程序。比如:
total=980000
iftotal>500000:
print("總價超過50萬")#條件成立,執(zhí)行打印。
沒有else,實際上與空的else等價。如果if后的條件不成立,那么計算機什么都不用執(zhí)行。2.小弟靠后站用縮進(jìn)來表明代碼的從屬關(guān)系,是Python的特色。正如我們在第1章中介紹的,用縮進(jìn)來標(biāo)記代碼關(guān)系的設(shè)計源自ABC語言。作為對比,我們可以看看C語言的寫法:
if(i>0){
x=1;
y=2;
}
這個程序的意思是,如果變量i大于0,我們將進(jìn)行括號中所包括的兩個賦值操作。在C語言中,用一個花括號來表示從屬于if的代碼塊。一般程序員也會在C語言中加入縮進(jìn),以便區(qū)分出指令的從屬關(guān)系。但縮進(jìn)并非強制的。下面沒有縮進(jìn)的代碼,在C語言中也可以正常執(zhí)行,與上面程序的運行結(jié)果沒有任何差別:
if(i>0){
x=1;
y=2;
}
在Python中,同樣的程序必須要寫成如下形式:
ifi>0:
x=1
y=2
在Python中,去掉了i>0周圍的括號,去除了每個語句句尾的分號,表示塊的花括號也消失了。多出來了if...之后的:(冒號),還有就是x=1和y=2前面有四個空格的縮進(jìn)。通過縮進(jìn),Python識別出這兩個語句是隸屬于if的。為了區(qū)分出隸屬關(guān)系,Python中的縮進(jìn)是強制的。下面的程序,將產(chǎn)生完全不同的效果:
ifi>0:
x=1
y=2
這里,從屬于if的只有x=1這一句,第二句賦值不再歸屬于if。無論如何,y都會被賦值為2。應(yīng)該說,現(xiàn)在大部分的主流語言,如C、C++、Java、JavaScript,都是用花括號來標(biāo)記程序塊的,縮進(jìn)也不是強制的。這一語法設(shè)計源自于流行一時的C語言。另一方面,盡管縮進(jìn)不是強制的,但有經(jīng)驗的程序員在用這些語言寫程序時,也會加入縮進(jìn),以便程序更易讀。很多編輯器也有給程序自動加縮進(jìn)的功能。Python的強制縮進(jìn)看起來非主流,實際上只是在語法層面上執(zhí)行了這一慣例,以便程序更好看,也更容易讀。這種以四個空格的縮進(jìn)來表示隸屬關(guān)系的書寫方式,還會在Python的其他語法結(jié)構(gòu)中看到。3.if的嵌套與elif再回到選擇結(jié)構(gòu)。選擇結(jié)構(gòu)讓程序擺脫了枯燥的指令式排列。程序的內(nèi)部可以出現(xiàn)分支一樣的結(jié)構(gòu)。根據(jù)條件不同,同一個程序可以工作于多變的環(huán)境。通過elif語法和嵌套使用if,程序可以有更加豐富多彩的分支方式。下面一個程序使用了elif結(jié)構(gòu)。根據(jù)條件的不同,程序有三個分支:
i=1
ifi>0:#條件1。由于i為1,這一部分將執(zhí)行。
print("positivei")
i=i+1
elifi==0:#條件2。該部分不執(zhí)行。
print("iis0")
i=i
*
10
else:#條件3。該部分不執(zhí)行。
print("negativei")
i=i-1
這里有三個塊,分別由if、elif和else引領(lǐng)。Python先檢測if的條件,如果發(fā)現(xiàn)if的條件為假,則跳過隸屬于if的程序塊,檢測elif的條件;如果elif的條件還是假,則執(zhí)行else塊。程序根據(jù)條件,只執(zhí)行三個分支中的一個。由于i的值是1,所以最終只有if部分被執(zhí)行。按照同樣的原理,你也可以在if和else之間增加多個elif,從而給程序開出更多的分支。我們還可以讓一個if結(jié)構(gòu)嵌套在另一個if結(jié)構(gòu)中:
i=5
ifi>1:#該條件成立,執(zhí)行內(nèi)部的代碼
print("ibiggerthan1")
print("good")
ifi>2:#嵌套的if結(jié)構(gòu),條件同樣成立。
print("ibiggerthan2")
print("evenbetter")
在進(jìn)行完第一個if判斷后,如果條件成立,那么程序依次運行,會遇到第二個if結(jié)構(gòu)。程序?qū)⒗^續(xù)根據(jù)條件判斷并決定是否執(zhí)行。第二個后面的程序塊相對于該if又縮進(jìn)了四個空格,成為“小弟的小弟”。進(jìn)一步縮進(jìn)的程序隸屬于內(nèi)層的if??偟膩碚f,借著if結(jié)構(gòu),我們給程序帶來了分支。根據(jù)條件的不同,程序?qū)⒆呱喜煌牡缆罚鐖D2-2所示。圖2-2if選擇結(jié)構(gòu)2.4計算機能循環(huán)1.for循環(huán)循環(huán)用于重復(fù)執(zhí)行一些程序塊,在Python中,循環(huán)有for和while兩種,我們先來看for循環(huán)。從2.3節(jié)的選擇結(jié)構(gòu),我們已經(jīng)看到了如何用縮進(jìn)來表示程序塊的隸屬關(guān)系。循環(huán)也會用到類似的寫法。隸屬于循環(huán)結(jié)構(gòu)的、需要重復(fù)的程序會被縮進(jìn),比如:
forain[3,4.4,"life"]:
print(a)#依次打印列表里的各個元素
這個循環(huán)就是每次從列表[3,4.4,"life"]中取出一個元素,然后將這個元素賦值給a,之后執(zhí)行隸屬于for的程序,也就是調(diào)用print()函數(shù),把這個元素打印出來??梢钥吹剑琭or的一個基本用法是在in后面跟一個序列:
for元素in序列:
statement
序列中元素的個數(shù)決定了循環(huán)重復(fù)的次數(shù)。示例中有3個元素,所以print()會執(zhí)行3次。也就是說,for循環(huán)的重復(fù)次數(shù)是確定的。for循環(huán)會依次從序列中取出元素,賦予給緊跟在for后面的變量,也就是上面示例中的a。因此,盡管執(zhí)行的語句都相同,但由于數(shù)據(jù)發(fā)生了變化,所以相同的語句在三次執(zhí)行后的效果也會發(fā)生變化。從序列中取出元素,再賦予給一個變量并在隸屬程序中使用,是for循環(huán)的一個便利之處。但有的時候,我們只是想簡單地重復(fù)特定的次數(shù),不想建立序列,那么我們可以使用Python提供的range()函數(shù):
foriinrange(5):
print("HelloWorld!")#打印五次
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年餐飲酒店人力資源服務(wù)合同
- 2024年重型鏟車租賃協(xié)議樣本版B版
- 寫作文的書知乎
- 2025年度環(huán)境保護補償貿(mào)易融資協(xié)議3篇
- 2025年度醫(yī)療設(shè)備采購合同范本及售后服務(wù)條款3篇
- 濮陽石油化工職業(yè)技術(shù)學(xué)院《診斷治療學(xué)概論》2023-2024學(xué)年第一學(xué)期期末試卷
- 云南體育運動職業(yè)技術(shù)學(xué)院《兒科學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 武漢光谷職業(yè)學(xué)院《飼料學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 揚州環(huán)境資源職業(yè)技術(shù)學(xué)院《病原微生物免疫與健康》2023-2024學(xué)年第一學(xué)期期末試卷
- 基坑土方回填監(jiān)理旁站記錄表
- 監(jiān)理日志表(標(biāo)準(zhǔn)模版)
- 視頻監(jiān)控系統(tǒng)PPT幻燈片課件(PPT 168頁)
- 線纜包覆擠塑模設(shè)計和原理
- GM∕T 0045-2016 金融數(shù)據(jù)密碼機技術(shù)規(guī)范
- 人力資源部年度工作計劃表(超級詳細(xì)版)
- 《輪機英語》試題(二三管輪)
- 部編版二年級語文下冊《蜘蛛開店》
- 北師大二年級數(shù)學(xué)上教學(xué)反思
- 200m3╱h凈化水處理站設(shè)計方案
- 空調(diào)系統(tǒng)維保記錄表格模板
- 《數(shù)學(xué)廣角——數(shù)與形》評課稿
評論
0/150
提交評論