Python程序設(shè)計(jì)課件 高波 第5-8章 面向?qū)ο?多線程_第1頁(yè)
Python程序設(shè)計(jì)課件 高波 第5-8章 面向?qū)ο?多線程_第2頁(yè)
Python程序設(shè)計(jì)課件 高波 第5-8章 面向?qū)ο?多線程_第3頁(yè)
Python程序設(shè)計(jì)課件 高波 第5-8章 面向?qū)ο?多線程_第4頁(yè)
Python程序設(shè)計(jì)課件 高波 第5-8章 面向?qū)ο?多線程_第5頁(yè)
已閱讀5頁(yè),還剩271頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第五章面向?qū)ο驪ython程序設(shè)計(jì)01面向?qū)ο蠛?jiǎn)介02類與對(duì)象03類的繼承與組合04本章回顧01面向?qū)ο竺嫦驅(qū)ο螅∣bjectOriented)是一種編程思想,是基于面向過(guò)程的編程思想慢慢發(fā)展而來(lái)的。面向?qū)ο笈c面向過(guò)程面向過(guò)程就是分析出解決問(wèn)題所需要的步驟,然后用函數(shù)把這些步驟一步一步實(shí)現(xiàn),使用的時(shí)候依次調(diào)用就可以了。而面向?qū)ο笫前褬?gòu)成問(wèn)題的事務(wù)分解成各個(gè)對(duì)象,建立對(duì)象的目的不是為了完成一個(gè)步驟,而是為了描敘某個(gè)事物在整個(gè)解決問(wèn)題的步驟中的行為,面向?qū)ο笫且环N“自下而上”的設(shè)計(jì)語(yǔ)言,先設(shè)計(jì)組件,再完成拼裝。面向?qū)ο笙噍^于面向過(guò)程有更強(qiáng)的靈活性和擴(kuò)展性。面向過(guò)程與面向?qū)ο笈e例以剪刀石頭布游戲?yàn)槔齺?lái)理解面向過(guò)程和面向?qū)ο笏枷氲膮^(qū)別,面向過(guò)程的設(shè)計(jì)思路就是按照步驟來(lái)實(shí)現(xiàn):①開(kāi)始游戲。②玩家1出剪刀或石頭或布。③玩家2出剪刀或石頭或布。④根據(jù)玩家出的結(jié)果判斷輸贏。⑤重復(fù)步驟2、3、4,直到退出游戲。面向?qū)ο蟮脑O(shè)計(jì)則是從另外的思路來(lái)解決問(wèn)題,整個(gè)游戲中玩家1和玩家2屬性和行為一致,可以用玩家類表示,判斷輸贏可以用游戲規(guī)則類表示,程序的實(shí)現(xiàn)步驟如下:①使用玩家類接收用戶輸入并將輸入結(jié)果傳遞給游戲規(guī)則類。②利用游戲規(guī)則類中的方法對(duì)輸贏進(jìn)行判定。從上面的案例可以看出,針對(duì)同一個(gè)問(wèn)題,面向過(guò)程和面向?qū)ο蠼鉀Q問(wèn)題的思路有很大差異,從面向過(guò)程到面向?qū)ο?,不僅僅是編程方式的改變,更重要的是思考方式的改變。面向過(guò)程與面向?qū)ο髤^(qū)別面向過(guò)程更注重步驟與過(guò)程,不注重職責(zé)與分工,在開(kāi)發(fā)簡(jiǎn)單系統(tǒng)可行,但面對(duì)復(fù)雜大型系統(tǒng)時(shí)代碼會(huì)冗雜。面向?qū)ο笞⒅芈氊?zé)與分工,完成需求前先確定職責(zé),再根據(jù)職責(zé)確定對(duì)象并封裝方法,最后根據(jù)業(yè)務(wù)需求讓不同對(duì)象調(diào)用不同方法。同時(shí)提到有面向過(guò)程和面向?qū)ο髤^(qū)別的總結(jié)表(下表)。面向?qū)ο蠡靖拍顚W(xué)習(xí)面向?qū)ο缶幊绦柘攘私庀嚓P(guān)概念。1.對(duì)象:在Python中一切皆為對(duì)象,如人、雞、花等都可表示為對(duì)象,具有唯一性,有屬性和行為,屬性是靜態(tài)部分如人的名字、性別等,行為是動(dòng)態(tài)部分如吃飯、睡覺(jué)、工作等。2.類:是具有相同屬性和方法的對(duì)象的集合,是對(duì)象的模板,可對(duì)共有的屬性和方法進(jìn)行定義,如狗的類有嘴、眼睛、腿等屬性和睡覺(jué)、吃東西、搖尾巴等行為,鄰居家小狗是該類的一個(gè)對(duì)象。3.實(shí)例化:創(chuàng)建類的實(shí)例即生成具體對(duì)象,如“狗”是類,自己養(yǎng)的寵物狗XX是實(shí)例化后的實(shí)例對(duì)象。類和對(duì)象的關(guān)系類和對(duì)象的關(guān)系可總結(jié)為以下幾點(diǎn):①類是對(duì)象的模板,對(duì)象是類的具體實(shí)例。②類是抽象的,對(duì)象是具體的。③每一個(gè)對(duì)象都是某個(gè)類的實(shí)例。面向?qū)ο蟪绦蛟O(shè)計(jì)的特點(diǎn)面向?qū)ο蟪绦蛟O(shè)計(jì)有封裝、繼承、多態(tài)三大特點(diǎn)。

封裝:是面向?qū)ο缶幊毯诵乃枷?,把客觀事物封裝成類,可將相同屬性和行為的對(duì)象封裝成類并隱藏不必要信息,確保類內(nèi)部數(shù)據(jù)完整。優(yōu)點(diǎn)包括減少耦合、可自由修改類內(nèi)部結(jié)構(gòu)、保護(hù)成員屬性、隱藏信息實(shí)現(xiàn)細(xì)節(jié)。

繼承:是面向?qū)ο蟪绦蛟O(shè)計(jì)基石,實(shí)現(xiàn)代碼復(fù)用。子類繼承父類特征和行為,可定義自己的屬性和方法。優(yōu)點(diǎn)有提高類代碼復(fù)用性、可維護(hù)性,使類之間產(chǎn)生關(guān)系且是多態(tài)前提。

多態(tài):允許不同類對(duì)象對(duì)同一消息有不同響應(yīng),通過(guò)動(dòng)態(tài)綁定實(shí)現(xiàn),同一操作作用不同對(duì)象有不同結(jié)果。存在條件為繼承、子類重寫父類方法、父類引用變量指向子類對(duì)象。02類與對(duì)象在生活中先有對(duì)象再有類,而在程序中是先有類才能有對(duì)象。在Python中,類的定義使用class關(guān)鍵字實(shí)現(xiàn),其語(yǔ)法格式如下:參數(shù)說(shuō)明如下表所示。類的定義類的定義舉例如下圖所示。類的定義類在定義時(shí)可以為其添加說(shuō)明文檔,說(shuō)明文檔放在字符串中,通常位于類內(nèi)部、所有代碼的最前面,可以通過(guò)內(nèi)置的help()函數(shù)或__doc__屬性獲取說(shuō)明文檔的內(nèi)容(和函數(shù)的說(shuō)明文檔類似),如右圖所示。類的實(shí)例化類定義好之后,相當(dāng)于有了一個(gè)模板,但沒(méi)有對(duì)象。對(duì)象的生成是通過(guò)類的實(shí)例化實(shí)現(xiàn)的,類的實(shí)例化語(yǔ)法如下:其中ClassName為類名,parameterlist為參數(shù)列表,類實(shí)例化時(shí)ClassName是必須指定的,是否有parameterlist要結(jié)合__init__()方法中的參數(shù)情況。創(chuàng)建__init__()方法__init__()方法類似于Java語(yǔ)言中的構(gòu)造方法,在類實(shí)例化時(shí)會(huì)自動(dòng)調(diào)用。__init__()方法必須包含一個(gè)self參數(shù),且必須是第一個(gè)參數(shù),如果沒(méi)有指定self參數(shù)的話,實(shí)例化時(shí)會(huì)報(bào)錯(cuò),如圖5-2所示。創(chuàng)建__init__()方法self參數(shù)是一個(gè)指向?qū)嵗旧淼囊茫糜谠L問(wèn)類中的屬性和方法。當(dāng)__init__()方法中只有一個(gè)self參數(shù)時(shí),實(shí)例化時(shí)不需要指定參數(shù),因?yàn)檎{(diào)用__init__()方法時(shí)會(huì)自動(dòng)傳遞self參數(shù),如圖5-3所示。創(chuàng)建__init__()方法在__init__()方法中,除了可以指定self參數(shù),還可以自定義一些其它參數(shù),舉例如【代碼5-2】所示。創(chuàng)建__init__()方法【代碼5-2】的運(yùn)行結(jié)果如圖5-4所示。類的屬性屬性是在類中定義的變量,有時(shí)也稱為特征,即類中客觀存在的靜態(tài)部分。根據(jù)屬性定義的位置不同,可分為類屬性和實(shí)例屬性。類屬性與實(shí)例屬性類屬性是在類中方法之外定義的屬性,實(shí)例屬性是定義在類的方法中的屬性,類屬性可以在類的所有實(shí)例之間共享值,實(shí)例屬性只作用于當(dāng)前實(shí)例中。在右圖中,類中方法外定義的屬性grade為類屬性,__init__()方法中定義的屬性name、sex和age為實(shí)例屬性。類屬性與實(shí)例屬性類屬性可以通過(guò)類名或?qū)ο螅▽?shí)例)名訪問(wèn),類屬性需通過(guò)類名來(lái)修改,類屬性修改后會(huì)作用于該類的所有實(shí)例中,如右圖所示。類屬性與實(shí)例屬性實(shí)例屬性只能通過(guò)對(duì)象名訪問(wèn),使用類名訪問(wèn)會(huì)報(bào)錯(cuò),如下圖所示。類屬性與實(shí)例屬性·實(shí)例屬性可以通過(guò)對(duì)象名修改,修改一個(gè)對(duì)象的實(shí)例屬性并不影響其它對(duì)象中的實(shí)例屬性,如下圖所示。屬性的訪問(wèn)權(quán)限類的屬性根據(jù)外部對(duì)其訪問(wèn)的權(quán)限,分為共有屬性、保護(hù)屬性和私有屬性,總結(jié)如下表所示。屬性的訪問(wèn)權(quán)限接下來(lái)我們定義一個(gè)Person類來(lái)舉例說(shuō)明,如右圖所示。屬性的訪問(wèn)權(quán)限在上頁(yè)代碼中,name是公有屬性,age是保護(hù)屬性,可以直接通過(guò)對(duì)象名訪問(wèn),如右圖所示。屬性的訪問(wèn)權(quán)限height和weight是私有屬性,需通過(guò)“實(shí)例名._類名__XX”方式訪問(wèn),直接通過(guò)對(duì)象名訪問(wèn)會(huì)報(bào)錯(cuò),如下圖所示。屬性的訪問(wèn)權(quán)限在實(shí)際開(kāi)發(fā)過(guò)程中,為了避免客戶端直接對(duì)屬性進(jìn)行修改,我們一般將屬性設(shè)置為私有,然后通過(guò)set方法設(shè)置值,通過(guò)get方法獲取值,如右圖所示。類的方法在5.2.1中,我們接觸過(guò)類的方法,即__init__()方法。這個(gè)方法用來(lái)初始化一個(gè)對(duì)象,在實(shí)例化時(shí)自動(dòng)執(zhí)行,如果一個(gè)類中沒(méi)有提供__init__()方法,Python將提供一個(gè)默認(rèn)的__init__()方法。實(shí)例方法init__()方法在類內(nèi)部有特殊的功能,屬于特殊方法,除此之外,我們也可以在類中自定義其它的方法,該方法是一種在類的實(shí)例上操作的函數(shù),所以叫做實(shí)例方法。實(shí)例方法的第一個(gè)參數(shù)必須是self,其語(yǔ)法格式如下:實(shí)例方法其中functionName為方法名,一般使用小駝峰法命名,self用來(lái)表示類的實(shí)例,parameterlist用于指定self以外的其它參數(shù),block是用于實(shí)現(xiàn)具體功能的方法體。關(guān)于實(shí)例方法的使用舉例如右圖所示。實(shí)例方法實(shí)例方法的訪問(wèn)權(quán)限實(shí)例方法的訪問(wèn)權(quán)限與類屬性的訪問(wèn)權(quán)限類似,可分為公有方法、保護(hù)方法和私有方法。實(shí)例方法的訪問(wèn)權(quán)限總結(jié)如下圖所示。實(shí)例方法的訪問(wèn)權(quán)限接下來(lái)我們改造之前的Person類,分別定義公有方法、保護(hù)方法和私有方法,如右圖所示。實(shí)例方法的訪問(wèn)權(quán)限類的實(shí)例化之后,公有方法可以直接訪問(wèn),如下圖所示。實(shí)例方法的訪問(wèn)權(quán)限保護(hù)方法通過(guò)單下劃線訪問(wèn),如右圖所示。私有方法不能在類外部訪問(wèn),不然會(huì)報(bào)錯(cuò),如右圖所示。實(shí)例方法的訪問(wèn)權(quán)限在公有方法judge_BMI()中使用代碼“BMI=self.__get_BMI2()”訪問(wèn)了私有方法,調(diào)用judge_BMI()方法的運(yùn)行結(jié)果如下圖所示。類方法類方法使用裝飾器“@classmethod”修飾,類方法的第一個(gè)參數(shù)必須是當(dāng)前類對(duì)象(一般約定為“cls”),通過(guò)這個(gè)參數(shù)來(lái)傳遞類的屬性和方法,類和實(shí)例對(duì)象都可以調(diào)用類方法。類方法的使用舉例如右圖所示。類方法運(yùn)行結(jié)果如下圖所示。類方法需要注意的是類方法中一定要有cls參數(shù),如果不提供參數(shù)的話會(huì)報(bào)錯(cuò),如右圖所示。靜態(tài)方法(2)靜態(tài)方法靜態(tài)方法使用裝飾器“@staticmethod”修飾,靜態(tài)方法與普通方法類似,不需要有self參數(shù)和cls參數(shù),一個(gè)類中的所有實(shí)例共享靜態(tài)方法,類和實(shí)例對(duì)象都可以調(diào)用靜態(tài)方法。我們將上頁(yè)代碼中的類方法修改成靜態(tài)方法,如右圖所示。靜態(tài)方法運(yùn)行結(jié)果如下圖所示。03類的繼承與組合繼承是實(shí)現(xiàn)代碼重用的重要手段,當(dāng)要編寫的類和之前已經(jīng)使用過(guò)的類有很多屬性和方法是相同的,且存在一定的繼承關(guān)系時(shí),即可使用繼承這種方式來(lái)達(dá)到代碼重用的目的。如之前使用過(guò)的Person類和Student類,Student類就可以繼承自Person類。父類與子類學(xué)習(xí)繼承需先了解父類和子類概念。在Python中,Object類是所有類的父類。繼承特性源于生活,如每個(gè)人從人類祖先繼承說(shuō)話、走路等行為,從父輩繼承相貌、身高等特征,同時(shí)每個(gè)人也有獨(dú)特的特征和行為。在Python中,父類和子類的關(guān)系可總結(jié)如下:子類繼承父類的屬性和方法。子類可以在父類的基礎(chǔ)上額外添加屬性和方法。子類可以重寫父類的方法。一個(gè)子類可以有多個(gè)父類,即多重繼承。繼承的語(yǔ)法Python中繼承的語(yǔ)法格式如下:參數(shù)說(shuō)明如下圖所示。繼承的語(yǔ)法接下來(lái)我們定義一個(gè)Animal類做為父類,Dog類和Cat類分別繼承Animal類,如右圖所示。繼承的語(yǔ)法運(yùn)行結(jié)果如下圖所示。方法重寫子類會(huì)繼承父類的方法,當(dāng)父類中的某個(gè)方法不適用于子類時(shí),子類可以對(duì)其進(jìn)行重寫。需要注意的是當(dāng)子類重寫父類的__init__方法時(shí),如果需要父類的構(gòu)造方法時(shí)需使用super關(guān)鍵字顯式地調(diào)用,如果子類不重寫__init__方法,實(shí)例化子類時(shí),會(huì)自動(dòng)調(diào)用父類定義的__init__方法。方法重寫右圖中,子類Dog沒(méi)有重寫父類的__init__方法,實(shí)例化時(shí)自動(dòng)調(diào)用了父類的__init__方法。當(dāng)子類重寫了__init__方法,但是不需要父類的構(gòu)造方法時(shí),子類被實(shí)例化時(shí)直接調(diào)用子類重寫后的__init__方法,如右圖所示。方法重寫方法重寫的使用舉例如右圖所示。方法重寫方法重寫運(yùn)行結(jié)果如下圖所示。方法重寫從上頁(yè)及其運(yùn)行結(jié)果可總結(jié)出:

1.子類Dog重寫了__init__()方法和personality()方法,重寫__init__()時(shí)通過(guò)“super().init(name,shout)”顯式調(diào)用父類的__init__()方法。

2.子類Cat重寫了personality()方法,未重寫__init__()方法,實(shí)例化時(shí)自動(dòng)調(diào)用父類__init__()方法。

3.實(shí)例化對(duì)象dog和cat都調(diào)用了父類定義的info()方法和各自重寫后的personality()方法,返回結(jié)果不同。類的組合代碼重用除繼承方式外還有類的組合,即在一個(gè)類中以另一個(gè)類的對(duì)象作為數(shù)據(jù)屬性。當(dāng)類之間差異顯著且一個(gè)大類由多個(gè)小類組成時(shí)可使用組合。例如電腦有品牌、顏色、內(nèi)存等信息,可分為基本信息、硬件、操作系統(tǒng)三類,計(jì)算機(jī)這個(gè)大類可看成由這些小類的對(duì)象組成,如右圖所示。類的組合類的組合運(yùn)行結(jié)果如右圖所示。在實(shí)際開(kāi)發(fā)過(guò)程中,我們可以結(jié)合業(yè)務(wù)需求,將繼承、組合兩種方式結(jié)合使用。案例【案例描述】馬戲團(tuán),是進(jìn)行馬戲表演的團(tuán)體組織。它起源于非常血腥殘酷的古羅馬角斗士斗獸場(chǎng)。當(dāng)時(shí)有“只有面包和馬戲”才能使羅馬人快樂(lè)的說(shuō)法。在英文里,馬戲團(tuán)叫做“Circus”,源自拉丁文“圓圈”的意思,指圓形露天競(jìng)技場(chǎng)?,F(xiàn)代的馬戲團(tuán)也在圓形場(chǎng)地中演出,因此演變成“馬戲團(tuán)”的意思。馬戲的主要內(nèi)容是動(dòng)物表演,之所以被稱為“馬戲”,是因?yàn)樽钤绲谋硌莸闹鹘鞘邱R,以后才陸續(xù)出現(xiàn)其它的動(dòng)物演員?!景咐蟆勘景咐M馬戲團(tuán)運(yùn)行流程,按照菜單選擇查看動(dòng)物基本信息(本馬戲團(tuán)中動(dòng)物演員包括但不限于海豚、猴子、獅子等)、隨機(jī)觀看表演、順序觀看表演等。案例本章回顧1.【多選】關(guān)于面向?qū)ο竺枋稣_的有()。A.面向?qū)ο螅∣bjectOriented)是一種編程思想,是基于面向過(guò)程的編程思想慢慢發(fā)展而來(lái)的B.面向?qū)ο笫前褬?gòu)成問(wèn)題的事務(wù)分解成各個(gè)對(duì)象,建立對(duì)象的目的不是為了完成一個(gè)步驟,而是為了描敘某個(gè)事物在整個(gè)解決問(wèn)題的步驟中的行為C.面向?qū)ο笫且环N“自下而上”的設(shè)計(jì)語(yǔ)言,先設(shè)計(jì)組件,再完成拼裝D.面向?qū)ο筮m用于簡(jiǎn)單系統(tǒng),容易理解2.【多選】關(guān)于面向過(guò)程描述正確的有()。A.面向過(guò)程就是分析出解決問(wèn)題所需要的步驟,然后用函數(shù)把這些步驟一步一步實(shí)現(xiàn),使用的時(shí)候依次調(diào)用就可以了B.面向過(guò)程是以過(guò)程/方法為中心來(lái)組織編程方式C.面向過(guò)程難以應(yīng)對(duì)復(fù)雜系統(tǒng),難以復(fù)用,不易維護(hù)、不易擴(kuò)展D.面向過(guò)程更注重的是步驟與過(guò)程,不注重職責(zé)與分工綜合練習(xí)3.【多選】關(guān)于類和對(duì)象的關(guān)系描述正確的有()。A.類是用來(lái)描述具有相同的屬性和方法的對(duì)象的集合B.類是對(duì)象的模板,對(duì)象是類的具體實(shí)例C.實(shí)例化就是創(chuàng)建一個(gè)類的實(shí)例,也就是生成類的具體對(duì)象D.類是抽象的,對(duì)象是具體的4.【多選】關(guān)于面向?qū)ο蟪绦蛟O(shè)計(jì)的特點(diǎn),描述正確的有()。A.封裝是面向?qū)ο缶幊痰暮诵乃枷隑.繼承是實(shí)現(xiàn)代碼復(fù)用的重要手段C.多態(tài)指允許不同類的對(duì)象對(duì)同一消息做出響應(yīng),即同一消息可以根據(jù)發(fā)送對(duì)象的不同而采用多種不同的行為方式D.繼承可以提高代碼的復(fù)用性和可維護(hù)性綜合練習(xí)5.【多選】關(guān)于類屬性與實(shí)例屬性描述正確的有()。A.類屬性是在類中方法之外定義的屬性,實(shí)例屬性是定義在類的方法中的屬性B.類的所有實(shí)例之間不可以共享類屬性的值C.類屬性可以通過(guò)類名或?qū)ο螅▽?shí)例)名訪問(wèn)D.實(shí)例屬性只能通過(guò)對(duì)象名訪問(wèn)6.【多選】關(guān)于類屬性的訪問(wèn)權(quán)限描述正確的有()。A.沒(méi)有以任何下劃線開(kāi)頭的屬性是公有屬性,可在類的外部直接訪問(wèn)B.以單下劃線“_”開(kāi)頭的屬性是保護(hù)屬性,只有其本身和子類能訪問(wèn)C.以雙下劃線“__”開(kāi)頭的屬性是私有屬性,只有該類本身可以訪問(wèn),子類不能訪問(wèn)D.私有屬性不能通過(guò)類的實(shí)例直接訪問(wèn),需通過(guò)“實(shí)例名._XX”來(lái)訪問(wèn)綜合練習(xí)7.定義類的關(guān)鍵字是()。A.function B.def

C.classD.define8.關(guān)于__init__()方法描述錯(cuò)誤的是()。A.__init__()方法類似于Java語(yǔ)言中的構(gòu)造方法,在類實(shí)例化時(shí)會(huì)自動(dòng)調(diào)用B.__init__()方法必須包含一個(gè)self參數(shù),且必須是第一個(gè)參數(shù)C.當(dāng)__init__()方法中只有一個(gè)self參數(shù)時(shí),實(shí)例化時(shí)也需要指定該參數(shù)D.self參數(shù)是一個(gè)指向?qū)嵗旧淼囊?,用于訪問(wèn)類中的屬性和方法9.關(guān)于類的方法,描述錯(cuò)誤的是()A.類方法使用裝飾器“@classmethod”修飾B.靜態(tài)方法使用裝飾器“@staticmethod”修飾C.類方法不需要有self參數(shù)和cls參數(shù)D.一個(gè)類中的所有實(shí)例共享靜態(tài)方法,類和實(shí)例對(duì)象都可以調(diào)用靜態(tài)方法綜合練習(xí)10.以下關(guān)于繼承的描述,錯(cuò)誤的是()。A.父類是指直接或間接被繼承的類,子類是指通過(guò)繼承派生出來(lái)的新類B.子類可以在父類的基礎(chǔ)上額外添加屬性和方法C.子類可以重寫父類的方法D.在Python中,一個(gè)子類只能有一個(gè)父類11.關(guān)于方法重寫,描述錯(cuò)誤的是()。A.子類會(huì)繼承父類的方法,當(dāng)父類中的某個(gè)方法不適用于子類時(shí),子類可以對(duì)其進(jìn)行重寫B(tài).當(dāng)子類重寫父類的__init__方法時(shí),如果需要父類的構(gòu)造方法時(shí)需使用super關(guān)鍵字顯式地調(diào)用C.如果子類不重寫__init__方法,實(shí)例化子類時(shí),會(huì)自動(dòng)調(diào)用父類定義的__init__方法D.子類一定要重寫父類的__init__方法綜合練習(xí)12.關(guān)于類的組合,描述錯(cuò)誤的是()。A.繼承和組合不能一起使用B.繼承和組合都是實(shí)現(xiàn)代碼重用的重要手段C.類的組合,就是在一個(gè)類中以另外一個(gè)類的對(duì)象作為數(shù)據(jù)屬性D.當(dāng)一個(gè)大類是由多個(gè)小類組成時(shí),可以使用組合13.簡(jiǎn)述面向?qū)ο笈c面向過(guò)程的區(qū)別。期待您的寶貴意見(jiàn)Python程序設(shè)計(jì)教學(xué)團(tuán)隊(duì)第六章

模塊Python程序設(shè)計(jì)01模塊、包和庫(kù)02常用標(biāo)準(zhǔn)庫(kù)模塊的使用03基于第三方庫(kù)的爬蟲(chóng)應(yīng)用04本章回顧01模塊、包和庫(kù)模塊是將功能封裝起來(lái),使用時(shí)直接導(dǎo)入,可提高代碼開(kāi)發(fā)效率、避免重復(fù)開(kāi)發(fā),類似函數(shù)和類有封裝思想,但模塊是更復(fù)雜功能的封裝容器。以洗衣機(jī)為例,將洗衣機(jī)類比為模塊,人們使用洗衣機(jī)無(wú)需關(guān)心其工作原理,如同使用模塊無(wú)需了解其具體實(shí)現(xiàn),只需使用其功能。

在開(kāi)發(fā)過(guò)程中,總是會(huì)接觸到模塊、包、庫(kù)等概念,這些概念簡(jiǎn)單理解就是函數(shù)、類、變量等可以封裝在模塊(module)中,多個(gè)模塊可以封裝到包(package)里面,多個(gè)包可以封裝到庫(kù)(library)里面。模塊及其導(dǎo)入方式我們?cè)诘谝徽碌臅r(shí)候,就接觸過(guò)模塊這個(gè)概念,那么到底什么是模塊呢?簡(jiǎn)單理解,模塊就是一個(gè)包含了許多功能/方法的文件,即每一個(gè).py文件都可以被當(dāng)成是一個(gè)模塊,模塊可以包含直接運(yùn)行的代碼塊、類、函數(shù)或這幾種的組合。導(dǎo)入模塊的常用方式有三種,分別是import語(yǔ)句、from…import語(yǔ)句和from…import*語(yǔ)句。模塊及其導(dǎo)入方式import語(yǔ)句import語(yǔ)句用于導(dǎo)入整個(gè)模塊,支持導(dǎo)入多個(gè)模塊,語(yǔ)法格式如下:

以我們之前使用過(guò)的隨機(jī)生成整數(shù)的函數(shù)randint為例,由于需要使用randint函數(shù),而randint函數(shù)位于random模塊下,所以在使用randint函數(shù)之前需要使用語(yǔ)句“import

random”進(jìn)行模塊導(dǎo)入,如下圖所示。模塊及其導(dǎo)入方式如果在使用randint函數(shù)之前沒(méi)有導(dǎo)入random模塊,將會(huì)報(bào)NameError錯(cuò)誤,提示“name'random'isnotdefined”,如下圖所示。模塊及其導(dǎo)入方式使用import語(yǔ)句的方式導(dǎo)入,因?yàn)槭菍?dǎo)入的整個(gè)模塊,所以需要使用“模塊名.函數(shù)名”的方式調(diào)用函數(shù)。除此之外,我們還可以使用as關(guān)鍵字對(duì)引入的模塊重命名,如下圖所示。模塊及其導(dǎo)入方式from…import語(yǔ)句模塊導(dǎo)入除了可以整個(gè)模塊都導(dǎo)入之外,也可以使用“from…import語(yǔ)句”只導(dǎo)入某個(gè)或某幾個(gè)函數(shù),語(yǔ)法格式如下:

使用此種方式導(dǎo)入,可以直接使用函數(shù)名進(jìn)行調(diào)用,還是以random模塊為例,如下圖所示。模塊及其導(dǎo)入方式from…import*語(yǔ)句使用“from…import*語(yǔ)句”可以導(dǎo)入一個(gè)模塊的所有內(nèi)容,舉例如下圖所示。自定義模塊自定義模塊就是根據(jù)業(yè)務(wù)需求自行定義的模塊,JupyterNotebook對(duì)自定義模塊的支持不是很友好,所以為了演示自定義模塊的使用,我們使用安裝Anaconda時(shí)自帶的另一個(gè)工具Spyder,如下圖所示。自定義模塊打開(kāi)Spyder,在本地電腦上找一個(gè)合適的位置新建一個(gè)文件夾“test_module”,然后在此文件夾下新建一個(gè)“animal_act.py”文件(File->NewFile),然后將“案例7:馬戲團(tuán)動(dòng)物表演”中的【代碼5-12】粘貼進(jìn)去,單擊“運(yùn)行按鈕”,看控制臺(tái)是否輸出正常,如下圖所示。此時(shí)“animal_act.py”文件就是一個(gè)自定義的模塊,想要引用這個(gè)模塊,分為同級(jí)目錄下引用和非同級(jí)目錄下引用兩種情況。自定義模塊同級(jí)目錄下引用我們?cè)诤退粋€(gè)文件夾“test_module”中新建一個(gè)“test.py”文件,此時(shí)如果想在“test.py”文件中引入自定義模塊“animal_act.py”,可以使用“import語(yǔ)句”直接導(dǎo)入,如下圖所示。自定義模塊非同級(jí)目錄下引用自定義模塊,直接用import無(wú)法找到,要借助sys模塊導(dǎo)入自定義模塊的path。以新建文件夾“test_module2”及其下的文件“test2.py”為例,若要在“test2.py”中引入非同級(jí)目錄下的自定義模塊“animal_act.py”,直接引入會(huì)報(bào)錯(cuò)。如下圖所示自定義模塊正確的引用方式如下所示。此時(shí)單擊“運(yùn)行按鈕”,可以正常運(yùn)行“animal_act.py”文件下的start()方法了,運(yùn)行結(jié)果如下圖所示。什么是包在Python中,包是一個(gè)分層次的文件目錄結(jié)構(gòu),是由模塊及子包、子包下的子包等組成的Python應(yīng)用環(huán)境。簡(jiǎn)單理解包就是文件夾,但是該文件夾下必須包含“__init__.py”文件(__init__.py文件內(nèi)容可以為空),也就是“__init__.py”文件用于標(biāo)識(shí)當(dāng)前文件夾是否為一個(gè)包?!癬_init__.py”文件的作用可總結(jié)為:

與普通目錄的區(qū)別標(biāo)識(shí),即用于標(biāo)識(shí)當(dāng)前文件夾是否為一個(gè)包。

編寫代碼,定義類、函數(shù)、變量等。包的使用為了更好地演示包的使用,我們還是使用Spyder工具。打開(kāi)Spyder,在本地電腦上找一個(gè)合適的位置新建一個(gè)文件夾“testpackage”,在此文件夾下新建一個(gè)空的“__init__.py”文件(Spyder中新建文件:File->NewFile),然后再分別建文件“testpackage1.py”和“testpackage2.py”,此時(shí)目錄結(jié)構(gòu)如下圖所示。包的使用文件“testpackage1.py”和“testpackage2.py”中的代碼分別如下所示。包的使用然后我們?cè)诎饷嫘陆ㄒ粋€(gè)文件“usepackage.py”,在文件中引入包并使用其中的模塊,如下所示運(yùn)行“usepackage.py”文件,結(jié)果如下圖所示。標(biāo)準(zhǔn)庫(kù)與常用標(biāo)準(zhǔn)庫(kù)模塊庫(kù)是為了方便管理與安裝,將能夠?qū)崿F(xiàn)某一功能的模塊和包封裝而成的集合。根據(jù)庫(kù)是否已經(jīng)包含在Python官方安裝包中,可以將其分為標(biāo)準(zhǔn)庫(kù)和第三方庫(kù)。標(biāo)準(zhǔn)庫(kù)就是在Python官方安裝包中包含的庫(kù),即安裝好Python后就具有的庫(kù)。標(biāo)準(zhǔn)庫(kù)中的模塊就是標(biāo)準(zhǔn)庫(kù)模塊,常用的標(biāo)準(zhǔn)庫(kù)模塊總結(jié)如表所示。第三方庫(kù)第三方庫(kù)就是在Python官方安裝包中不包含的庫(kù),第三方庫(kù)中的模塊即第三方模塊。想要使用第三方庫(kù)中的模塊,需要先安裝第三方庫(kù)。第三方庫(kù)可以在命令行窗口使用pip命令在線安裝,也可以先下載相應(yīng)的第三方庫(kù)安裝程序,然后再進(jìn)行安裝。Python的一大優(yōu)勢(shì)就是有豐富且易用的第三方庫(kù)及模塊,省去了大量重復(fù)造輪子的時(shí)間,常用的第三方模塊有用于圖像處理的pillow,用于處理URL資源的requests,用于數(shù)據(jù)可視化的matplotlib等。02常用標(biāo)準(zhǔn)庫(kù)模塊的使用在實(shí)際開(kāi)發(fā)中我們要經(jīng)常使用系統(tǒng)的標(biāo)準(zhǔn)庫(kù)模塊,比如我們想實(shí)現(xiàn)字符串匹配功能,可以使用正則表達(dá)式re模塊;想要實(shí)現(xiàn)時(shí)間相關(guān)功能,可以使用time模塊、datetime模塊;想要實(shí)現(xiàn)數(shù)學(xué)運(yùn)算,可以使用math模塊;想要實(shí)現(xiàn)加密功能,可以使用hashlib模塊;本節(jié)我們將對(duì)上述模塊的基本使用進(jìn)行介紹。正則表達(dá)式是用于匹配字符串中字符組合的模式,可以用來(lái)檢查一個(gè)串是否含有某種子串、將匹配的子串替換或者從某個(gè)串中取出符合某個(gè)條件的子串等。正則表達(dá)式是用來(lái)匹配字符串的非常強(qiáng)大的工具,正則表達(dá)式主要由普通字符、元字符、重復(fù)限定符等組成。普通字符就是大小寫字母、數(shù)字等,用于匹配自身。正則表達(dá)式可以是單個(gè)字符、也可以是由上訴字符任意組合形成的字符集合。正則表達(dá)式介紹元字符元字符是構(gòu)造正則表達(dá)式的一種基本元素,常用的元字符總結(jié)如右表所示。了解了元字符之后,我們就可以開(kāi)始寫一些簡(jiǎn)單的正則表達(dá)式了,如11位手機(jī)號(hào)碼的正則表達(dá)式可表示如下:正則表達(dá)式介紹重復(fù)限定符上述舉例的表示手機(jī)號(hào)的正則表達(dá)式有很多重復(fù)的元字符“\d”,為了解決這一問(wèn)題,正則表達(dá)式中提供了重復(fù)限定符。常用的重復(fù)限定符總結(jié)如表所示。正則表達(dá)式介紹有了上一個(gè)表中的重復(fù)限定符后,我們之前舉例的11位手機(jī)號(hào)碼的正則表達(dá)式就可以寫成如下的形式:分組

正則表達(dá)式中用小括號(hào)“()”來(lái)做分組,也就是小括號(hào)中的內(nèi)容作為一個(gè)整體。因此181號(hào)段電話號(hào)碼的正則表達(dá)式可表示如下:正則表達(dá)式介紹選擇字符還是以手機(jī)號(hào)碼為例,大家都知道,國(guó)內(nèi)的手機(jī)號(hào)都來(lái)自電信、聯(lián)通、移動(dòng)三大運(yùn)營(yíng)商,而每個(gè)運(yùn)營(yíng)商提供的號(hào)段是不一樣的,以電信手機(jī)號(hào)為例,其號(hào)段有199、191、189、181、180、177、173、153和133。此時(shí)我們想寫電信手機(jī)號(hào)的正則表達(dá)式,就需要用到選擇字符或“|”來(lái)實(shí)現(xiàn),其正則表達(dá)式如下:區(qū)間正則表達(dá)式中提供中括號(hào)“[]”來(lái)表示區(qū)間條件,如數(shù)字0~9可以寫成[0-9],字母a~z可以寫成[a-z]。需要注意的是字符“^”在區(qū)間中不再表示字符串的開(kāi)始,而是代表排除的意思,即匹配不在區(qū)間范圍內(nèi)的字符,如[^6]代表除6以外的字符。正則表達(dá)式介紹轉(zhuǎn)義字符在正則表達(dá)式中點(diǎn)“.”代表任意字符,而我們需要單純的使用點(diǎn)“.”這個(gè)字符的時(shí)候,就需要用到轉(zhuǎn)義字符了。正則表達(dá)式中的轉(zhuǎn)義字符就是在特殊字符之前加上反斜杠“\”,將其變?yōu)槠胀ㄗ址?。比如IP地址(,等)的正則表達(dá)式可表示如下:使用re模塊實(shí)現(xiàn)正則表達(dá)式Python中的re模塊用于實(shí)現(xiàn)正則表達(dá)式相關(guān)操作,本節(jié)主要介紹一些常用屬性和方法的使用。re模塊常用標(biāo)志位修飾符re模塊具有一些屬性用于做為標(biāo)志位的修飾符,用來(lái)控制正則表達(dá)式的匹配方式,如不區(qū)分大小寫、多行匹配等,總結(jié)如表所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式re模塊常用方法compile()方法:pile()方法是用于優(yōu)化正則表達(dá)式的,可以將正則表達(dá)式轉(zhuǎn)化為對(duì)象,然后多次調(diào)用正則表達(dá)式就重復(fù)利用這個(gè)正則對(duì)象,可以實(shí)現(xiàn)更有效率的匹配。compile()方法生成的對(duì)象需要和match()、search()和findall()等方法搭配使用,單獨(dú)使用沒(méi)有意義。compile()方法的使用舉例如下:使用re模塊實(shí)現(xiàn)正則表達(dá)式match()方法。match()方法用于從字符串開(kāi)始位置進(jìn)行匹配,即匹配以XXX開(kāi)頭的字符串,其基本語(yǔ)法如下:參數(shù)說(shuō)明如表6-5所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式使用match()方法匹配成功會(huì)返回一個(gè)Match對(duì)象,匹配失敗返回None,如圖所示。上圖中的例子,我們使用了標(biāo)志位修飾符re.I忽略大小寫,如將re.I刪除,運(yùn)行結(jié)果將返回2個(gè)None,如下圖所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式search()方法。search()方法用于掃描整個(gè)字符串并返回第一個(gè)成功的匹配,即匹配第一次出現(xiàn)的XXX,語(yǔ)法格式與match()方法類似。search()方法匹配成功也是返回一個(gè)Match對(duì)象,匹配失敗返回None,如下圖所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式從上兩圖的運(yùn)行結(jié)果可看出match()方法和search()方法的區(qū)別,match()方法只匹配以給定正則開(kāi)始的字符串,而search()方法搜索整個(gè)字符串,直到找到一個(gè)匹配。match()方法相當(dāng)于在search()方法的正則表達(dá)式最前面加了一個(gè)符號(hào)“^”。使用match()方法和search()方法匹配成功后返回的Match對(duì)象也具有其屬性和方法,常用的總結(jié)如右表所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式關(guān)于Match對(duì)象的使用舉例如左圖所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式

findall()方法。

findall()方法用于在字符串中搜索與給定正則匹配的所有子串,并以列表形式返回,如果有多個(gè)匹配模式,則返回元組列表,如果沒(méi)有找到匹配的,則返回空列表。findall()方法的語(yǔ)法格式與match()、search()方法類似,不同的是match()、search()方法只匹配一次,findall()方法匹配所有符合條件的子串。

接下來(lái)使用一個(gè)輸入QQ郵箱獲取QQ號(hào)碼的案例來(lái)說(shuō)明findall()方法的使用,如下所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式上訴代碼的運(yùn)行結(jié)果如下圖所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式sub()方法。sub()方法用于實(shí)現(xiàn)字符串的替換,即按照正則規(guī)則去尋找被替換的內(nèi)容,其語(yǔ)法格式如下:參數(shù)說(shuō)明如表所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式sub()方法的使用舉例如下所示。上訴代碼的運(yùn)行結(jié)果如下圖所示。

split()方法。

split()方法用于實(shí)現(xiàn)字符串的分割,即將字符串按照正則分割成子串,并以列表的形式返回,其語(yǔ)法格式如下:使用re模塊實(shí)現(xiàn)正則表達(dá)式參數(shù)說(shuō)明如表所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式split()方法的使用舉例如下所示。上訴代碼的運(yùn)行結(jié)果如下圖所示。使用re模塊實(shí)現(xiàn)正則表達(dá)式以上介紹了6個(gè)re模塊中的常用方法,現(xiàn)將其總結(jié)如表所示。日期和時(shí)間模塊(1)time模塊中的時(shí)間格式在time模塊中時(shí)間表現(xiàn)的格式主要有時(shí)間戳、時(shí)間元組、格式化時(shí)間三種。時(shí)間戳,即timestamp,表示的是從1970年1月1日00:00:00開(kāi)始按秒計(jì)算的偏移量,適用于做日期運(yùn)算。時(shí)間元組,即struct_time,共有九個(gè)元素組,如表所示。time模塊格式化時(shí)間,即format_time,已格式化的結(jié)構(gòu)使時(shí)間更具可讀性,包括自定義格式和固定格式。關(guān)于格式化時(shí)間的相關(guān)符號(hào)總結(jié)如表所示。time模塊(2)time模塊常用方法time模塊的常用方法包括time()、sleep()、localtime()等,現(xiàn)將其總結(jié)如表所示。time模塊time模塊的常用方法使用舉例如右所示。datetime模塊datatime模塊在time模塊基礎(chǔ)上重新進(jìn)行了封裝,提供更多更多好用的類供我們使用,常用的包括date、time、datetime、timedelta等。datatime模塊包含MAXYEAR和MINYEAR兩個(gè)常量,分別是能表示的最大年份(9999)和最小年份(1)。(1)date類datatime模塊中的date類用于表示日期,其主要由year(年)、month(月)及day(日)三部分構(gòu)成,date對(duì)象的格式如下所示:datetime模塊date類常用的屬性和方法總結(jié)如表示。datetime模塊date類的使用舉例如下所示。datetime模塊上訴代碼的運(yùn)行結(jié)果如下圖所示。(2)time類datatime模塊中的time類用于表示時(shí)間,其主要由hour(小時(shí))、minute(分鐘)、second(秒)、microsecond(毫秒)和tzinfo(時(shí)區(qū)信息)五部分組成,time對(duì)象的格式如下所示:datetime模塊time類常用的屬性和方法于date類相似,使用舉例如右所示。代碼的運(yùn)行結(jié)果如下圖所示。datetime模塊(3)datetime類datatime模塊中的datetime類用于表示日期和時(shí)間,可以看成是date類和time類的結(jié)合,datetime類大部分的方法和屬性都繼承于date類和time類。datetime對(duì)象的格式如下所示:datetime模塊datetime類的使用舉例如下所示。datetime類中除了繼承date類和time類的方法,還有其特有的方法,總結(jié)如表所示。datetime模塊上訴代碼的運(yùn)行結(jié)果如下圖所示。datetime模塊(4)timedelta類datatime模塊中的timedelta類用于做時(shí)間運(yùn)算,一般與date類、datetime類結(jié)合使用。timedelta對(duì)象的格式如下所示:

timedelta類的使用舉例如代碼所示。運(yùn)行結(jié)果如下圖所示。加密模塊與其它常用模塊Python中的hashlib模塊提供加密的相關(guān)操作,包含MD5和SHA加密,支持md5,sha1,sha224,sha256,sha384,sha512等算法?!D5與SHAMD5全稱Message-DigestAlgorithm5,是廣泛使用的密碼散列函數(shù),能產(chǎn)生128位(16字節(jié))散列值,保障信息傳輸?shù)耐暾耘c一致性。SHA全稱SecureHashAlgorithm,是基于MD5產(chǎn)生的算法家族,包括sha1、sha224、sha256等多種算法。MD5和SHA都是不可逆的摘要算法,原理是通過(guò)函數(shù)將任意長(zhǎng)度數(shù)據(jù)轉(zhuǎn)換為固定長(zhǎng)度的數(shù)據(jù)串。hashlib模塊的使用hashlib模塊的使用可分為創(chuàng)建hash對(duì)象、更新hash對(duì)象和返回摘要三步,其常用屬性和方法總結(jié)如表所示。hashlib模塊的使用hashlib模塊的使用舉例如下圖所示。上訴代碼的運(yùn)行結(jié)果如下圖所示。其它常用模塊總結(jié)除了上述介紹的常用標(biāo)準(zhǔn)庫(kù)模塊之外,sys模塊、random模塊、math模塊也經(jīng)常使用,現(xiàn)將其常用方法、屬性總結(jié)如表所示。其它常用模塊總結(jié)其它常用模塊總結(jié)其中sys模塊中的modules.keys()方法用于返回所有已經(jīng)導(dǎo)入的模塊列表,運(yùn)行效果如下圖所示。03基于第三方庫(kù)的爬蟲(chóng)應(yīng)用很多編程語(yǔ)言都可以編寫爬蟲(chóng)程序,但是使用Python語(yǔ)言編寫爬蟲(chóng)無(wú)疑是最簡(jiǎn)單、最合適的,也有很多同學(xué)是因?yàn)榱私馀老x(chóng)才知道了Python。這一切都要?dú)w功于Python的豐富類庫(kù),可以方便高效地下載網(wǎng)頁(yè)和解析網(wǎng)頁(yè)?!ぞW(wǎng)絡(luò)爬蟲(chóng)概述

網(wǎng)絡(luò)爬蟲(chóng),又被稱為網(wǎng)頁(yè)蜘蛛,網(wǎng)絡(luò)機(jī)器人,是一種按照一定的規(guī)則,自動(dòng)地抓取萬(wàn)維網(wǎng)信息的程序或者腳本,已被廣泛應(yīng)用于互聯(lián)網(wǎng)領(lǐng)域。網(wǎng)絡(luò)爬蟲(chóng)是一種數(shù)據(jù)采集工具,如我們想對(duì)某網(wǎng)站進(jìn)行分析,那么待分析的數(shù)據(jù)去哪里獲取呢?此時(shí)就可以考慮使用網(wǎng)絡(luò)爬蟲(chóng)進(jìn)行爬取。網(wǎng)頁(yè)基礎(chǔ)由于網(wǎng)絡(luò)爬蟲(chóng)主要是爬取網(wǎng)頁(yè)的數(shù)據(jù),那么在學(xué)習(xí)爬蟲(chóng)之前,首先我們需要先了解網(wǎng)頁(yè)的基礎(chǔ)知識(shí)。當(dāng)我們打開(kāi)瀏覽器,在地址欄中輸入U(xiǎn)RL(UniformResourceLocator,統(tǒng)一資源定位器),如輸入“”,即可出現(xiàn)百度的首頁(yè)。我們可以單擊鍵盤上的“F12”打開(kāi)開(kāi)發(fā)者工具查看,如下圖所示。網(wǎng)頁(yè)基礎(chǔ)(1)訪問(wèn)網(wǎng)頁(yè)的流程從圖6-29中我們可看到Request和Response的一些信息,其實(shí)從輸入U(xiǎn)RL到我們看到頁(yè)面,其流程可總結(jié)如下:①輸入U(xiǎn)RL。②瀏覽器給Web服務(wù)器發(fā)送一個(gè)Request。③Web服務(wù)器接到Request后進(jìn)行處理,生成相應(yīng)的Response,然后發(fā)送給瀏覽器。④瀏覽器解析Response中的HTML,這樣我們就看到了網(wǎng)頁(yè)。(2)HTTP協(xié)議上述提到的Request和Response是HTTP協(xié)議中的請(qǐng)求和響應(yīng)。HTTP,即HyperTextTransferProtocol,超文本傳輸協(xié)議,是一種基于請(qǐng)求與響應(yīng)模式的、無(wú)狀態(tài)的應(yīng)用層協(xié)議。HTTP是網(wǎng)頁(yè)中數(shù)據(jù)通信的基礎(chǔ),當(dāng)我們?cè)跒g覽器鍵入任何一個(gè)URL時(shí),都是在發(fā)送一次HTTP請(qǐng)求。網(wǎng)頁(yè)基礎(chǔ)HTTP請(qǐng)求由請(qǐng)求行、請(qǐng)求頭和請(qǐng)求正文組成。其中請(qǐng)求正文就是一些發(fā)送的數(shù)據(jù),請(qǐng)求頭允許客戶端向服務(wù)器端傳遞請(qǐng)求的附加信息以及客戶端自身的信息(如用戶標(biāo)識(shí),主機(jī)名等),請(qǐng)求行以一個(gè)方法符號(hào)開(kāi)頭,以空格分開(kāi),后面跟著請(qǐng)求的URI和協(xié)議的版本,格式如下所示:參數(shù)說(shuō)明如表所示。網(wǎng)頁(yè)基礎(chǔ)HTTP響應(yīng)與HTTP請(qǐng)求類似,也是由三部分組成,分別是狀態(tài)行、響應(yīng)頭和響應(yīng)正文。狀態(tài)行的格式如下:參數(shù)說(shuō)明如表6-18所示。網(wǎng)頁(yè)基礎(chǔ)通過(guò)網(wǎng)頁(yè)開(kāi)發(fā)者工具查看上述訪問(wèn)百度頁(yè)面的請(qǐng)求頭和響應(yīng)頭信息分別如下圖所示。網(wǎng)絡(luò)爬蟲(chóng)的一般流程熟悉了網(wǎng)頁(yè)基礎(chǔ)知識(shí)之后,接下來(lái)我們看一下網(wǎng)絡(luò)爬蟲(chóng)的一般流程。①獲取待爬取的URL/URL隊(duì)列,發(fā)送Request。②通過(guò)Request獲取Response內(nèi)容(HTML、Json字符串、二進(jìn)制數(shù)據(jù)等)。③將得到的Response內(nèi)容進(jìn)行解析(使用正則表達(dá)式、網(wǎng)頁(yè)解析庫(kù)等)。④將解析后的數(shù)據(jù)進(jìn)行保存。上述流程簡(jiǎn)單理解就是第1步和第2步是網(wǎng)頁(yè)下載,第3步是網(wǎng)頁(yè)解析,第4步為數(shù)據(jù)存儲(chǔ)。爬蟲(chóng)相關(guān)庫(kù)介紹網(wǎng)絡(luò)爬蟲(chóng)主要由網(wǎng)頁(yè)下載、網(wǎng)頁(yè)解析和數(shù)據(jù)存儲(chǔ)三部分組成。網(wǎng)頁(yè)下載:Python中可使用標(biāo)準(zhǔn)庫(kù)的Urllib模塊或第三方庫(kù)Requests,Requests比Urllib更方便高效,本節(jié)重點(diǎn)介紹Requests。網(wǎng)頁(yè)解析:可使用正則表達(dá)式或第三方庫(kù)BeautifulSoup等,正則表達(dá)式已在6.2.1介紹,本節(jié)主要介紹BeautifulSoup庫(kù)。數(shù)據(jù)存儲(chǔ):可使用純文本、關(guān)系型數(shù)據(jù)庫(kù)(如MySQL、Oracle、SQLServer等)、非關(guān)系型數(shù)據(jù)庫(kù)(如MongoDB、Redis等),數(shù)據(jù)存儲(chǔ)部分在7.2介紹。網(wǎng)頁(yè)下載庫(kù)Requests介紹

Requests是基于Urllib開(kāi)發(fā)的,使用Apache2Licensed開(kāi)源協(xié)議的HTTP庫(kù),Request是一個(gè)第三方庫(kù),需要使用pip命令進(jìn)行安裝(pipinstallrequests)

(1)Requests庫(kù)的常用屬性/方法Requests庫(kù)的常用屬性/方法總結(jié)如表所示。網(wǎng)頁(yè)下載庫(kù)Requests介紹(2)Requests庫(kù)的基本使用Requests的使用很簡(jiǎn)單,還是以訪問(wèn)百度網(wǎng)頁(yè)為例,如右圖所示。網(wǎng)頁(yè)下載庫(kù)Requests介紹上訴代碼的運(yùn)行結(jié)果如圖所示。網(wǎng)頁(yè)下載庫(kù)Requests介紹(3)攜帶頭部信息發(fā)送請(qǐng)求在上訴代碼中,我們?cè)L問(wèn)的是百度首頁(yè),狀態(tài)碼是“200”,代表訪問(wèn)成功,而大多數(shù)時(shí)候,我們直接訪問(wèn)網(wǎng)頁(yè)時(shí),會(huì)出現(xiàn)403Forbidden,代表訪問(wèn)被拒絕,如右圖所示。出現(xiàn)右圖這種錯(cuò)誤的原因是,該網(wǎng)頁(yè)進(jìn)行了反爬蟲(chóng)設(shè)置,此時(shí)如果想要成功訪問(wèn)此網(wǎng)頁(yè),可以通過(guò)模擬瀏覽器的頭部信息“User-Agent”來(lái)實(shí)現(xiàn)?!癠ser-Agent”信息可以在開(kāi)發(fā)者工具中查看,如下圖所示。網(wǎng)頁(yè)下載庫(kù)Requests介紹網(wǎng)頁(yè)下載庫(kù)Requests介紹接下來(lái)我們攜帶頭部信息,再一次訪問(wèn)知乎首頁(yè),如下圖所示。網(wǎng)頁(yè)下載庫(kù)Requests介紹上訴代碼的運(yùn)行結(jié)果如下圖所示。BeautifulSoup介紹網(wǎng)頁(yè)解析庫(kù)BeautifulSoup介紹BeautifulSoup是一個(gè)解析HTML/XML文件的第三方庫(kù),主要用于從HTML/XML文件中提取數(shù)據(jù),其提供一些簡(jiǎn)單的函數(shù)來(lái)處理導(dǎo)航、搜索、修改分析樹(shù)等功能。使用BeautifulSoup時(shí)不需要考慮編碼方式,它會(huì)自動(dòng)將輸入文檔轉(zhuǎn)換為Unicode編碼,輸出文檔轉(zhuǎn)換為utf-8編碼。BeautifulSoup介紹(1)BeautifulSoup庫(kù)的導(dǎo)入BeautifulSoup3目前已經(jīng)停止開(kāi)發(fā),現(xiàn)在項(xiàng)目中使用的是BeautifulSoup4(可以使用命令“pipinstallbeautifulsoup4”進(jìn)行安裝),不過(guò)它已經(jīng)被移植到bs4中,也就是說(shuō)導(dǎo)入時(shí)直接使用“importBeautifulSoup”會(huì)報(bào)錯(cuò),需要使用語(yǔ)句“frombs4importBeautifulSoup”進(jìn)行導(dǎo)入,如下圖所示。BeautifulSoup介紹(2)BeautifulSoup解析器BeautifulSoup在解析時(shí)依賴解析器,它除了支持Python標(biāo)準(zhǔn)庫(kù)中的HTML解析器外,還支持一些第三方解析器,總結(jié)如表所示。BeautifulSoup介紹(3)BeautifulSoup的基本使用由于BeautifulSoup庫(kù)是用于解析HTML文件的,所以為了演示BeautifulSoup的使用,我們首先新建一個(gè)簡(jiǎn)單的HTML文件test.html,如下圖所示。BeautifulSoup介紹BeautifulSoup4能將復(fù)雜HTML文檔轉(zhuǎn)換為復(fù)雜樹(shù)形結(jié)構(gòu),其中每個(gè)節(jié)點(diǎn)都是Python對(duì)象,這些對(duì)象可歸納為Tag、NavigableString、BeautifulSoup和Comment這四種。Tag:可簡(jiǎn)單理解為HTML標(biāo)簽,能通過(guò)BeautifulSoup對(duì)象加標(biāo)簽名獲取,但這種方式查找的是所有內(nèi)容中第一個(gè)符合要求的標(biāo)簽。NavigableString:是標(biāo)簽的內(nèi)容,通過(guò)“.string”可獲取。BeautifulSoup對(duì)象:代表文檔的全部?jī)?nèi)容,可看作特殊的Tag。Comment對(duì)象:代表注釋內(nèi)容,是特殊類型的NavigableString,輸出內(nèi)容時(shí)不包含注釋符號(hào),解析含注釋內(nèi)容的文件時(shí)使用前最好先做判斷。BeautifulSoup介紹接下來(lái)對(duì)對(duì)上述test.html文件進(jìn)行解析,如右圖所示。代碼的運(yùn)行結(jié)果如下圖所示。BeautifulSoup介紹我們可以使用type()方法查看Tag、NavigableString、BeautifulSoup和Comment的具體類型,如右圖所示。BeautifulSoup介紹(4)BeautifulSoup遍歷文檔樹(shù)常用屬性/方法在使用BeautifulSoup遍歷文檔樹(shù)時(shí),可以獲取父節(jié)點(diǎn)、子節(jié)點(diǎn)、兄弟節(jié)點(diǎn)等,相關(guān)屬性/方法總結(jié)如表所示。案例【案例描述】近年來(lái)電影產(chǎn)業(yè)迅速發(fā)展,電影已成為藝術(shù)與娛樂(lè)的載體,與電影相關(guān)的數(shù)據(jù)越來(lái)越多,豆瓣作為中國(guó)最大的電影分享與評(píng)論社區(qū),收錄了百萬(wàn)條影片和影人的資料,記錄千萬(wàn)影迷的觀影感受,可為觀影提供決策?!景咐蟆勘景咐饕康氖谦@取豆瓣Top250電影,共有10頁(yè),首先獲取每頁(yè)網(wǎng)頁(yè)鏈接要求爬取每部電影的中文名稱、評(píng)分、評(píng)分人數(shù)和導(dǎo)演、主演等相關(guān)信息,如下圖所示。案例本章回顧1.【多選】模塊的導(dǎo)入方式有()。A.import語(yǔ)句B.from…import語(yǔ)句C.from…import*語(yǔ)句 D.import…in語(yǔ)句2.【多選】關(guān)于模塊的描述正確的有()。A.模塊就是一個(gè)包含了許多功能/方法的文件B.每一個(gè).py文件都可以被當(dāng)成是一個(gè)模塊C.模塊可以包含直接運(yùn)行的代碼塊、類、函數(shù)或這幾種的組合D.可以使用“from…import*語(yǔ)句”導(dǎo)入一個(gè)模塊的所有內(nèi)容3.【多選】關(guān)于模塊、包和庫(kù)的描述,以下正確的有()。A.庫(kù)是為了方便管理與安裝,將能夠?qū)崿F(xiàn)某一功能的模塊和包封裝而成的集合B.包是由模塊及子包、子包下的子包等組成的Python應(yīng)用環(huán)境C.簡(jiǎn)單理解包就是文件夾,該文件夾下可以不包含“__init__.py”文件D.根據(jù)庫(kù)是否已經(jīng)包含在Python官方安裝包中,可以將其分為標(biāo)準(zhǔn)庫(kù)和第三方庫(kù)本章回顧4.以下不屬于Python標(biāo)準(zhǔn)庫(kù)的模塊是()。A.requests B.re C.math D.time5.以下關(guān)于正則表達(dá)式的描述錯(cuò)誤的是()。A.正則表達(dá)式是用于匹配字符串中字符組合的模式B.正則表達(dá)式可以用來(lái)檢查一個(gè)串是否含有某種子串、將匹配的子串替換或者從某個(gè)串中取出符合某個(gè)條件的子串等C.正則表達(dá)式主要由普通字符、元字符、重復(fù)限定符等組成D.正則表達(dá)式不能是單個(gè)字符6.關(guān)于正則表達(dá)式的元字符,以下描述錯(cuò)誤的是()。A.字符“^”用于匹配字符串的開(kāi)始B.字符“\d”用于匹配個(gè)數(shù)字字符C.字符“\s”用于匹配任意非空白字符D.字符“\w”用于匹配字母、數(shù)字、下劃線或漢字本章回顧7.關(guān)于正則表達(dá)式的重復(fù)限定符,以下描述錯(cuò)誤的是()。A.字符“{n}”用于匹配前面的字符n次B.字符“+”用于匹配前面的字符零次或多次C.字符“{n,}”用于匹配前面的字符至少n次D.字符“+”匹配前面的字符一次或多次8.關(guān)于日期和時(shí)間模塊,以下描述錯(cuò)誤的是()。A.在time模塊中時(shí)間表現(xiàn)的格式主要有時(shí)間戳、時(shí)間元組、格式化時(shí)間三種B.datatime模塊在time模塊基礎(chǔ)上重新進(jìn)行了封裝C.datatime模塊中的date類用于表示日期D.datatime模塊中的time類用于表示日期和時(shí)間9.以下關(guān)于爬蟲(chóng)的相關(guān)描述,錯(cuò)誤的是()。A.網(wǎng)絡(luò)爬蟲(chóng)是一種按照一定的規(guī)則,自動(dòng)地抓取萬(wàn)維網(wǎng)信息的程序或者腳本B.由于網(wǎng)絡(luò)爬蟲(chóng)主要是爬取網(wǎng)頁(yè)的數(shù)據(jù),所以需要了解一些網(wǎng)頁(yè)基礎(chǔ)知識(shí)C.網(wǎng)絡(luò)爬蟲(chóng)的一般流程可總結(jié)為網(wǎng)頁(yè)下載、網(wǎng)頁(yè)解析和數(shù)據(jù)存儲(chǔ)三部分D.在網(wǎng)頁(yè)下載環(huán)節(jié),可以使用Urllib,Requests和BeautifulSoup本章回顧10.以下關(guān)于Requests庫(kù)的描述,錯(cuò)誤的是()。A.Requests是基于Urllib開(kāi)發(fā)的B.Request是Python標(biāo)準(zhǔn)庫(kù)C.Request中的get()方法,用于使用get方式發(fā)送請(qǐng)求D.使用Request發(fā)送請(qǐng)求時(shí),可以攜帶headers信息11.以下關(guān)于BeautifulSoup的描述,錯(cuò)誤的是()。A.BeautifulSoup是一個(gè)解析HTML/XML文件的第三方庫(kù)B.使用BeautifulSoup時(shí)不需要考慮編碼方式C.可以使用“importBeautifulSoup”進(jìn)行導(dǎo)入D.BeautifulSoup在解析時(shí)依賴解析器12.請(qǐng)列舉3個(gè)Python常用的標(biāo)準(zhǔn)庫(kù)模塊。期待您的寶貴意見(jiàn)Python程序設(shè)計(jì)教學(xué)團(tuán)隊(duì)第七章異常處理與文件操作Python程序設(shè)計(jì)01異常處理02文件操作03本章回顧異常處理與文件操作程序設(shè)計(jì)要求程序有健壯性,但運(yùn)行時(shí)存在導(dǎo)致程序不能正常運(yùn)行的不確定因素,為增強(qiáng)交互性和便于診斷錯(cuò)誤,要將不確定因素解釋為異常并處理。在實(shí)際開(kāi)發(fā)中異常處理必不可少,文件操作使用頻率高(包括讀寫、復(fù)制等)且操作過(guò)程中常需異常處理,因此將二者放在一章介紹。01異常處理

異常是在程序運(yùn)行過(guò)程中,影響程序正常執(zhí)行的一個(gè)事件。當(dāng)Python腳本發(fā)生異常時(shí)我們需要捕獲處理它,否則程序會(huì)終止執(zhí)行。本節(jié)將對(duì)常見(jiàn)的內(nèi)置異常、異常處理語(yǔ)句和自定義異常進(jìn)行介紹。Python常用內(nèi)置異常我們之前遇到的NameError、SyntaxError、TypeError等都是異常,Python常見(jiàn)的內(nèi)置異??偨Y(jié)如表所示。Python中異常繼承關(guān)系Python中所有異常的基類是BaseException,所有常規(guī)錯(cuò)誤的基類是Exception,所有的警告基類是Warning,主要異常類的繼承關(guān)系如下圖所示。異常處理語(yǔ)句在程序開(kāi)發(fā)過(guò)程中,有些異常是在輸入不合法時(shí)才會(huì)出現(xiàn),此時(shí)我們可以對(duì)可能出現(xiàn)異常的情況進(jìn)行處理。Python中異常處理的語(yǔ)句有try...except、try...except...else和try...except...finally三種。1.try...except語(yǔ)句捕捉異??梢允褂胻ry...except語(yǔ)句,try語(yǔ)句塊用來(lái)檢測(cè)錯(cuò)誤,except語(yǔ)句捕獲異常信息并處理。在使用時(shí),try語(yǔ)句塊中放入可能發(fā)生錯(cuò)誤的代碼,except語(yǔ)句塊中放入處理結(jié)果,當(dāng)try語(yǔ)句塊中代碼出現(xiàn)錯(cuò)誤時(shí)就執(zhí)行except語(yǔ)句塊中的代碼,若try語(yǔ)句塊中代碼沒(méi)有出現(xiàn)錯(cuò)誤則except語(yǔ)句塊中的代碼不會(huì)執(zhí)行。異常處理語(yǔ)句

(1)語(yǔ)法格式與參數(shù)說(shuō)明try...except語(yǔ)句的語(yǔ)法格式如下:參數(shù)說(shuō)明如表所示。異常處理語(yǔ)句(2)try...except語(yǔ)句的使用接下來(lái)我們演示try...except語(yǔ)句的使用,首先定義一個(gè)計(jì)算銷量的函數(shù)count(),如下所示。如果沒(méi)有做任何異常處理,當(dāng)輸入單價(jià)為0時(shí),將引發(fā)“ZeroDivisionError”異常,如右圖所示。異常處理語(yǔ)句此時(shí)我們使用try...except語(yǔ)句進(jìn)

行異常處理,將count()方法放到try語(yǔ)句塊中,將發(fā)生錯(cuò)誤的提示信息放到except中,如下圖所示。

運(yùn)行【代碼7-1】,此時(shí)再將price輸入為0,將不會(huì)出現(xiàn)“ZeroDivisionError”異常,而是輸出except中的提示信息,結(jié)果如下圖所示。異常處理語(yǔ)句(3)多異常處理目前我們只處理了“ZeroDivisionError”異常,由于在定義count()函數(shù)時(shí),price參數(shù)的類型時(shí)int,若輸入小數(shù),將會(huì)引發(fā)“ValueError”異常,如下圖所示。異常處理語(yǔ)句此時(shí)我們可以再一個(gè)except語(yǔ)句對(duì)ValueError異常進(jìn)行處理,如右圖所示。從右圖中可以看出,此時(shí)若再將price輸入為小數(shù),將不會(huì)出現(xiàn)“ValueError”異常,而是打印except中的提示信息。異常處理語(yǔ)句2.try...except...else語(yǔ)句與try...except...finally語(yǔ)句在上述異常處理語(yǔ)句try...except基礎(chǔ)上,還可以增加else語(yǔ)句和finally語(yǔ)句,else語(yǔ)句的作用是當(dāng)try語(yǔ)句中沒(méi)有出現(xiàn)異常時(shí)執(zhí)行,finally語(yǔ)句是無(wú)論程序運(yùn)行中是否發(fā)生異常都會(huì)執(zhí)行。try...except語(yǔ)句、try...except...else語(yǔ)句和try...except...finally語(yǔ)句的執(zhí)行邏輯如右圖所示。異常處理語(yǔ)句還是上面的案例,在上訴代碼的基礎(chǔ)上增加else語(yǔ)句塊和finally語(yǔ)句塊,如右圖所示。異常處理語(yǔ)句上圖代碼的運(yùn)行結(jié)果可總結(jié)如下圖所示。自定義異常在程序開(kāi)發(fā)過(guò)程中,當(dāng)使用標(biāo)準(zhǔn)內(nèi)置異常不能滿足業(yè)務(wù)需求時(shí),就需要自定義異常。自定義異常需要直接或者間接繼承“Exception”異常類,然后使用raise語(yǔ)句拋出異常。自定義異常的應(yīng)用舉例如右圖所示。自定義異常上訴代碼的運(yùn)行結(jié)果如下圖所示。02文件操作由于大部分?jǐn)?shù)據(jù)都是通過(guò)文件進(jìn)行存儲(chǔ)的,所以文件操作在程序開(kāi)發(fā)過(guò)程中是比較重要的一部分,也是程序員必須掌握的知識(shí)點(diǎn)。本節(jié)將介紹Python內(nèi)置文件對(duì)象File的基本操作和Excel文件的基本操作。文件基本操作1.文件分類我們?cè)谌粘I罨蚬ぷ髦薪佑|的文件類型有很多,如Word文件、PPT文件、音頻文件、視頻文件等。而無(wú)論何種類型的文件,在內(nèi)存或磁盤上最終都是以二進(jìn)制編碼存儲(chǔ)的。所以根據(jù)邏輯上編碼的不同,文件只分為文本文件和二進(jìn)制文件兩類。(1)文本文件文本文件存儲(chǔ)的是人類可以直接閱讀的字符,采用的是字符編碼,如ASCII、Unicode編碼、GBK、UTF-8等。文本文件經(jīng)過(guò)編解碼過(guò)程就可以轉(zhuǎn)換成人類理解的信息,編碼過(guò)程就是將字符轉(zhuǎn)換成二進(jìn)制,解碼過(guò)程就是將二進(jìn)制還原成字符。文件基本操作(2)二進(jìn)制文件二進(jìn)制文件存儲(chǔ)的是字符以外的其它信息,包括圖片、聲音、視頻等,采用的是值編碼,以字符串的形式存儲(chǔ)。二進(jìn)制文件是按照一定的規(guī)則,把信息轉(zhuǎn)換成二進(jìn)制存儲(chǔ)到文件中,但由于圖片、聲音、視頻格式轉(zhuǎn)換比較復(fù)雜,而且各有各的標(biāo)準(zhǔn),所以為了簡(jiǎn)化將其歸為一類。2.文件的打開(kāi)和關(guān)閉(1)文件打開(kāi)函數(shù)在Python中,想要操作文件首先需要打開(kāi)并創(chuàng)建一個(gè)文件對(duì)象,通過(guò)open()函數(shù)即可實(shí)現(xiàn)文件打開(kāi),其語(yǔ)法格式如下:文件基本操作參數(shù)說(shuō)明如右表所示。參數(shù)“access_mode”

的取值如右表所示。文件基本操作文件基本操作參數(shù)“buffering”的取值如表所示。

正常情況下,程序運(yùn)行在內(nèi)存中,而緩沖區(qū)就是一個(gè)內(nèi)存空間,它可以視為一個(gè)FIFO(先進(jìn)先出)隊(duì)列,當(dāng)緩沖區(qū)達(dá)到閾值或者滿了的時(shí)候,數(shù)據(jù)會(huì)被flush到磁盤。需要注意的是,對(duì)于參數(shù)“buffering”一般建議使用默認(rèn)的緩沖區(qū)設(shè)置,除非明確知道緩沖區(qū)所需大小。文件基本操作(2)文件關(guān)閉函數(shù)文件打開(kāi)之后,需要及時(shí)進(jìn)行關(guān)閉,通過(guò)close()函數(shù)即可實(shí)現(xiàn)文件關(guān)閉,其語(yǔ)法格式如下:其中file代表之前打開(kāi)的、待關(guān)閉的文件對(duì)象。文件操作一般需要和異常處理語(yǔ)句結(jié)合使用,而close()函數(shù)一般會(huì)放在finally語(yǔ)句塊中。close()函數(shù)運(yùn)行時(shí)會(huì)先刷新緩沖區(qū)還沒(méi)寫入的信息,然后再關(guān)閉文件。文件基本操作(3)文件打開(kāi)和關(guān)閉的應(yīng)用接下來(lái)我們演示一下文件打開(kāi)和閉關(guān)函數(shù)的使用,首先在JupyterNotebook中新建一個(gè)文本文件,如右圖所示。然后將新建的文件重命名為“test.txt”,并編輯一些文本內(nèi)容,如右圖所示。文件基本操作此時(shí)可以使用代碼“file=open('test.txt')”打開(kāi)文件,然后訪問(wèn)file對(duì)象,運(yùn)行結(jié)果如右圖所示。從上圖中可以看出,由于我們沒(méi)有傳遞參數(shù)“access_mode”,所以是采用默認(rèn)方式“r”(只讀)打開(kāi),編碼是“cp936”。如果我們想使用編碼“utf-8”打開(kāi),可以使用代碼“file=open('test.txt',encoding='utf-8')”,此時(shí)再訪問(wèn)file文件,編碼即變?yōu)榱恕皍tf-8”,如右圖所示。文件基本操作有了文件對(duì)象之后,還可以通過(guò)mode、name、closed屬性分別獲取打開(kāi)模式、名字和是否已經(jīng)關(guān)閉信息,如右圖所示。如果我們打開(kāi)一個(gè)不存在的文件,將會(huì)出現(xiàn)“FileNotFoundError”異常,如右圖所示。文件基本操作此時(shí)可以將打開(kāi)文件進(jìn)行異常處理,并在finally語(yǔ)句中進(jìn)行文件關(guān)閉,如右圖所示。文件基本操作上訴代碼的運(yùn)行結(jié)果分別如圖1和圖2所示。文件基本操作3.文件讀寫Python中的file對(duì)象提供了一些方法用于對(duì)文件進(jìn)行讀寫,常用的總結(jié)如表所示。文件基本操作以下是一個(gè)讀寫文件的小案例。下圖代碼的運(yùn)行結(jié)果如下圖所示。文件基本操作需要注意的是,在讀寫模式下如果是先寫后讀,寫入后由于文件指針會(huì)移動(dòng)到文件尾,想要讀取文件內(nèi)容需要將文件指針移動(dòng)到文件頭位置(f.seek(0))。運(yùn)行完上圖代碼之后,由于我們之前沒(méi)“test1.txt”文件,在“w+”讀寫模式下,如果文件不存在,會(huì)創(chuàng)建一個(gè)新文件,此時(shí)可發(fā)現(xiàn)JupyterNotebook中多了一個(gè)文件“test1.txt”,文件的內(nèi)容如下圖所示。文件基本操作上訴代碼中是使用的read()函數(shù)讀取數(shù)據(jù),接下來(lái)分別使用readline()和readlines(),查看它們之間的區(qū)別,如下圖所示。使用os模塊操作文件及目錄Python中的os模塊及其子模塊os.path提供了一些方法用來(lái)處理文件和目錄。1.文件處理os模塊分別提供了rename()函數(shù)和remove()函數(shù)來(lái)重命名和刪除文件,rename()函數(shù)主要傳遞兩個(gè)參數(shù),第一個(gè)參數(shù)是文件原名,第二個(gè)參數(shù)為文件的新名字,其語(yǔ)法格式如下:使用os模塊操作文件及目錄remove()函數(shù)的參數(shù)就是待刪除文件的路徑,如想要?jiǎng)h除上面重命名后的“test2.txt”文件,可使用代碼“os.remove('test2.txt')”。

如我們要將前面代碼中的文件“test1.txt”重命名為“test2.txt”,可使用代碼“os.rename('test1.txt','test2.txt')”,如下圖所示。使用os模塊操作文件及目錄2.目錄操作(1)創(chuàng)建目錄os模塊中最基礎(chǔ)的用于創(chuàng)建目錄的函數(shù)是os.mkdir(path),如我們想在E盤下新建一個(gè)目錄test,可使用代碼“os.mkdir('E:\\test')”,但若使用此方法時(shí),E盤已存在test目錄,此時(shí)會(huì)報(bào)錯(cuò),如下圖所示。使用os模塊操作文件及目錄遇到此種情況,可先使用os.path.exists(path)函數(shù)判斷目錄是否存在,當(dāng)目錄不存在時(shí)再進(jìn)行創(chuàng)建,如右圖所示。此時(shí)運(yùn)行代碼,結(jié)果如右圖所示。使用os模塊操作文件及目錄創(chuàng)建的目錄可以在指定路徑下查看,如下圖所示。使用os模塊操作文件及目錄(2)創(chuàng)建多級(jí)目錄上述的mkdir()函數(shù)用于創(chuàng)建一級(jí)目錄,如果給定的目錄有多級(jí),且最后一級(jí)的上級(jí)目錄不存在,使用mkdir()函數(shù)會(huì)出現(xiàn)FileNotFoundError異常,如下圖所示。使用os模塊操作文件及目錄此時(shí)可以使用os.makedirs(path)函數(shù)遞歸創(chuàng)建多級(jí)目錄,如下圖所示。使用os模塊操作文件及目錄(3)刪除目錄刪除目錄可以使用os.rmdir(path)函數(shù),但是需要注意的是,此函數(shù)只能刪除空目錄,如我們刪除前面代碼中創(chuàng)建的目錄“E:\\test\\test1”,代碼為“os.rmdir('E:\\test\\test1')”,運(yùn)行此代碼后,再次查看test文件夾,已經(jīng)為空了(代表刪除成功),如下圖所示。使用os模塊操作文件及目錄此時(shí)如果我們?cè)趖est中新建一個(gè)“test.txt”文件,此時(shí)再刪除test文件夾,會(huì)出現(xiàn)OSError錯(cuò)誤,如下圖所示。(1)

遍歷目錄使用os模塊中的walk()函數(shù)可以獲取指定目錄下的所有目錄及文件,其語(yǔ)法格式如下:使用os模塊操作文件及目錄參數(shù)說(shuō)明如表所示。接下來(lái)對(duì)walk()函數(shù)的使用進(jìn)行舉例,假設(shè)有一個(gè)目錄結(jié)構(gòu)如右圖所示。使用os模塊操作文件及目錄遍歷上圖中目錄的代碼如右圖所示。右圖代碼的運(yùn)行結(jié)果如右圖所示。使用os模塊操作文件及目錄上圖的運(yùn)行遍歷結(jié)果顯示得并不友好,為了看起來(lái)更舒適,可結(jié)合拼接路徑函數(shù)os.path.join()實(shí)現(xiàn)更好的展示效果,如右圖所示。上訴代碼的運(yùn)行結(jié)果如下圖所示。使用os模塊操作文件及目錄3.

常用方法總結(jié)除了上述介紹的文件處理和目錄操作的相關(guān)方法,os模塊和其子模塊os.path還提供了獲取當(dāng)前工作目錄、獲取絕對(duì)路徑等方法,為了方便大家記憶,現(xiàn)將常用的方法總結(jié)如表所示。Excel文件操作在開(kāi)發(fā)過(guò)程中,經(jīng)常需要處理Excel文件,Python中提供了一些用于處理excel文件的第三方模塊。使用xlwt模塊對(duì)以“.xls”為后綴(2003以前的版本)的表格文件進(jìn)行寫入。使用xlrd模塊對(duì)以“.xls”為后綴(2003以前的版本)的表格文件進(jìn)行讀取。xlutils模塊可以實(shí)現(xiàn)xlwt和xlrd之間的轉(zhuǎn)換。使用openpyxl模塊實(shí)現(xiàn)對(duì)以“.xlsx”為后綴(2007以后的版本)的表格文件的讀寫。Excel文件操作1.使用xlwt模塊實(shí)現(xiàn)寫入xls文件使用xlwt模塊寫入xls文件一般需要5個(gè)步驟,如右圖所示。Excel文件操作接下來(lái)舉例說(shuō)明,如右圖所示。Excel文件操作運(yùn)行上圖代碼,查看E盤,發(fā)現(xiàn)其下已經(jīng)多了一個(gè)“test.xls”文件,打開(kāi)此文件查看內(nèi)容,如右圖所示。Excel文件操作在寫入文件時(shí),還可以進(jìn)行列寬、行高、居中等設(shè)置,我們將之前的案例進(jìn)行改造,如下圖所示。Excel文件操作運(yùn)行代碼,得到新的文件“test.xls”,內(nèi)容如下圖所示。和前圖相比,上圖中的行高、列寬都有了變化,且數(shù)據(jù)已居中顯示。Excel文件操作2.使用xlrd模塊讀取xls文件使用xlrd模塊讀取xls文件可總結(jié)為4步,如右圖所示。Excel文件操作接下來(lái)讀取前面代碼中生成的“test.xls”文件,如下圖所示。Excel文件操作上訴代碼的運(yùn)行結(jié)果如下圖所示。Excel文件操作3.使用xlutils模塊實(shí)現(xiàn)xlwt和xlrd之間的轉(zhuǎn)換由于使用xlrd模塊中的open_workbook()函數(shù)讀取xls文件返回的“xlrd.book.Book”類型的對(duì)象是只讀的,不能對(duì)其進(jìn)行修改。而如果我們想要實(shí)現(xiàn)讀取xls文件后對(duì)其進(jìn)行修改,就要借助于xlutils模塊。如果此Python環(huán)境中沒(méi)有xlutils模塊,可以使用命令“pipinstallxlutils”進(jìn)行安裝,如下圖所示。Excel文件操作xlutils.copy模塊的copy()方法可以將“xlrd.book.Book”類型轉(zhuǎn)換為xlwt模塊中的“xlwt.Workbook.Workbook”類型,如下圖所示。Excel文件操作接下來(lái)舉一個(gè)讀取xls文件,然后修改保存的例子,如下圖所示。Excel文件操作運(yùn)行上圖代碼,發(fā)現(xiàn)E盤多了一個(gè)文件“test2.xls”,打開(kāi)發(fā)現(xiàn)其有兩個(gè)工作表,其內(nèi)容如下圖所示。Excel文件操作4.使用openpyxl模塊進(jìn)行xlsx文件的讀寫對(duì)于xlsx格式的Excel文件讀寫可以使用第三方模塊openpyxl實(shí)現(xiàn)。(1)使用openpyxl寫入xlsx文件使用openpyxl寫入xlsx文件的思路與上文介紹的使用xlwt模塊寫入xls文件類似,都是首先導(dǎo)入模塊,然后創(chuàng)建工作薄、工作表、寫入數(shù)據(jù),最后保存到指定文件,舉例如右圖所示。Excel文件操作運(yùn)行上圖代碼,發(fā)現(xiàn)E盤多了一個(gè)文件“test3.xlsx”,其有兩個(gè)工作表,內(nèi)容下圖所示。Excel文件操作與寫入xls文件時(shí)類似,在寫入xlsx文件時(shí)也可以設(shè)置行高、列寬、對(duì)齊方式等,如右圖所示。Excel文件操作運(yùn)行上訴代碼之后,打開(kāi)E盤下的“test4.xlsx”文件,內(nèi)容如下圖所示。Excel文件操作(2)openpyxl模塊相關(guān)屬性介紹上述案例中我們主要用到的是openpyxl模塊的Workbook、Worksheet和Cell對(duì)象,其常用屬性總結(jié)如表所示。Excel文件操作(3)使用openpyxl讀取xlsx文件使用openpyxl讀取xlsx文件的思路與上文介紹的使用xlrd模塊讀取xls文件類似,都是首先導(dǎo)入模塊,然后獲取工作薄、工作表,最后獲取工作表中的內(nèi)容,舉例如右圖所示。Excel文件操作上訴代碼的運(yùn)行結(jié)果如下圖所示。案例【案例描述】GDP(GrossDomesticProduct),即國(guó)內(nèi)生產(chǎn)總值,是一個(gè)國(guó)家(或地區(qū))所有常住單位在一定時(shí)期內(nèi)生產(chǎn)活動(dòng)的最終成果。GDP是國(guó)民經(jīng)濟(jì)核算的核心指標(biāo),也是衡量一個(gè)國(guó)家或地區(qū)經(jīng)濟(jì)狀況和發(fā)展水平的重要指標(biāo)?,F(xiàn)有一份表格中記錄了187個(gè)國(guó)家從2000年至2017年的的GDP數(shù)據(jù)(單位:萬(wàn)億元),如圖7-42所示。案例【案例要求】由于表中數(shù)據(jù)較多,為了方便查看,現(xiàn)設(shè)計(jì)一個(gè)程序用于從當(dāng)前數(shù)據(jù)表中提取某個(gè)國(guó)家的GDP信息到新的工作表中,提取后可以適當(dāng)進(jìn)行格式處理?!緦?shí)現(xiàn)思路】①讀取表格中數(shù)據(jù)。②根據(jù)需求獲取某個(gè)國(guó)家的GDP信息。③將獲取到的某個(gè)國(guó)家GDP信息保存到一個(gè)新的工作表中。④可在其中結(jié)合異常處理的方法。案例【案例代碼】案例

【運(yùn)行結(jié)果】運(yùn)行上圖代碼,在輸入框中輸入中國(guó),控制臺(tái)輸出結(jié)果如圖所示。案例E盤中的gdp3.xlsx內(nèi)容如右圖所示。03本章回顧本章共分為兩小節(jié)內(nèi)容,第一小節(jié)主要介紹異常處理,包括異常概述、異常處理語(yǔ)句和自定義異常。第二小節(jié)主要介紹文件操作,包括文本文件的操作、二進(jìn)制文件的操作、Excel文件操作等內(nèi)容。本章回顧【綜合練習(xí)】1.【多選】Python中的異常處理語(yǔ)句包括()。A.try...except語(yǔ)句B.try...except...else語(yǔ)句C.try...except...finally語(yǔ)句D.try…catch語(yǔ)句2.【多選】以下關(guān)于Python異常的描述,正確的有()。A.異常是在程序運(yùn)行過(guò)程中,影響程序正常執(zhí)行的一個(gè)事件B.BaseException是所有異常的基類C.Exception是所有異常的基類D.RuntimeError代表一般的運(yùn)行時(shí)錯(cuò)誤本章回顧3.【多選】以下關(guān)于Python異常處理語(yǔ)句的描述,正確的有()。A.在Python中,捕捉異??梢允褂胻ry...except語(yǔ)句B.try語(yǔ)句塊用來(lái)檢測(cè)錯(cuò)誤C.except語(yǔ)句用于捕獲異常信息并處理D.finally語(yǔ)句是無(wú)論程序運(yùn)行中是否發(fā)生異常都會(huì)執(zhí)行4.【多選】根據(jù)邏輯上的編碼不同,文件可分類為()。A.文本文件 B.圖片 C.二進(jìn)制文件 D.視頻文件本章回顧5.關(guān)于文件基本操作,以下描述錯(cuò)誤的是()。A.open()函數(shù)用于打開(kāi)文件B.c

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論