python入门学习[看漫画学Python:有趣、有料、好玩、好用读书笔记]
寫在前面:本文中絕大多數(shù)圖片來源于圖書:看漫畫學(xué)Python:有趣、有料、好玩、好用,本文僅供個(gè)人學(xué)習(xí)使用,如有侵權(quán),請聯(lián)系刪除。
學(xué)習(xí)編程語言最好的方式就是多寫,多寫,多寫!!!哪有什么快速掌握,能快速的只有入門。看起來的輕松都是付出的結(jié)果。
文章目錄
- 01編程基礎(chǔ)那點(diǎn)兒事
- 02數(shù)字類型的數(shù)據(jù)
- 03運(yùn)算符
- 運(yùn)算符的優(yōu)先級???
- 04程序流程控制
- 05容器類型的數(shù)據(jù)
- 序列
- 元組
- 集合
- 字典
- 06字符串
- 07函數(shù)
- 08類與對象
- 封裝性
- 繼承性
- 多態(tài)性
- 09異常處理
- 10常用的內(nèi)置模塊
- 11文件讀寫
- 13網(wǎng)絡(luò)通信
- 參考資料
01編程基礎(chǔ)那點(diǎn)兒事
標(biāo)識符
python標(biāo)識符的規(guī)則
關(guān)鍵字
定義:關(guān)鍵字是由語言本身定義好的、有特殊含義的代碼元素。
python只有33個(gè)關(guān)鍵字,而且只有False、True和None的首字符大寫,其他關(guān)鍵字全部小寫。
來源:看漫畫學(xué)Python:有趣、有料、好玩、好用
變量
為一個(gè)變量賦值的同時(shí)就聲明了該變量,該變量的數(shù)據(jù)類型就是賦值數(shù)據(jù)所屬的類型,該變量還可以接收其他類型的數(shù)據(jù)。
語句
python代碼是由關(guān)鍵字、標(biāo)識符、表達(dá)式和語句等構(gòu)成的,語句是代碼的重要組成部分。
在python中,一行代碼表示一條語句,在一般情況下結(jié)束時(shí)不加分號。
來源:看漫畫學(xué)Python:有趣、有料、好玩、好用
模塊
在python中一個(gè)模塊就是一個(gè)文件,模塊是保存代碼的最小單位,在模塊中可以聲明變量、函數(shù)、屬性和類等python代碼元素。
一個(gè)模塊可以訪問另一個(gè)模塊嗎?
當(dāng)然可以,但是需要導(dǎo)入語句的幫忙,導(dǎo)入語句有以下三種形式。
import<模塊名>:
通過這種方式會導(dǎo)入m2模塊的所有代碼元素,在訪問時(shí)需要加前綴“m2.”
from<模塊名>import<代碼元素>:
通過這種方式會導(dǎo)入m2中的x變量,在訪問時(shí)不需要加前綴“m2.”
from<模塊名>import<代碼元素>as<代碼元素別名>:
與②類似,在當(dāng)前m1模塊的代碼元素(x變量)與要導(dǎo)入的m2模塊的代碼元素(x變量)名稱有沖突時(shí),可以給要導(dǎo)入的代碼元素(m2中的x)一個(gè)別名x2
舉例:
總結(jié):一個(gè)模塊其實(shí)就是一個(gè)文件,在模塊中封裝了很多代碼元素。在實(shí)際的項(xiàng)目開發(fā)中,我們避免不了要使用別人的模塊,如果想導(dǎo)入所有內(nèi)容,則使用import語句;如果只想導(dǎo)入一個(gè)元素,使用from import語句;如果名稱有沖突,則使用from import as.
02數(shù)字類型的數(shù)據(jù)
來源:看漫畫學(xué)Python:有趣、有料、好玩、好用,下同
在Python中所有的數(shù)據(jù)類型都是類,每個(gè)數(shù)據(jù)值都是類的“實(shí)例”。
在Python中有6種主要的內(nèi)置數(shù)據(jù)類型:數(shù)字、字符串、列表、元組、集合和字典。列表、元組、集合和字典可以容納多項(xiàng)數(shù)據(jù),在本書中把它們統(tǒng)稱為容器類型的數(shù)據(jù)。
Python中的數(shù)字類型有4種:整數(shù)類型、浮點(diǎn)類型、復(fù)數(shù)類型和布爾類型。需要注意的是,布爾類型也是數(shù)字類型,它事實(shí)上是整數(shù)類型的一種。
整數(shù)類型
Python中的整數(shù)類型為int類,整數(shù)類型的范圍可以很大,表示很大的整數(shù),只受所在計(jì)算機(jī)硬件的限制。
來源:看漫畫學(xué)Python:有趣、有料、好玩、好用,下同
浮點(diǎn)類型
浮點(diǎn)類型主要用來存儲小數(shù)數(shù)值,Python的浮點(diǎn)類型為float類。Python只支持雙精度浮點(diǎn)類型,而且是與本機(jī)相關(guān)的。
復(fù)數(shù)類型
整數(shù)和浮點(diǎn)數(shù)(小數(shù))在數(shù)學(xué)中被統(tǒng)稱為實(shí)數(shù)。與實(shí)數(shù)對應(yīng)的是復(fù)數(shù),復(fù)數(shù)在數(shù)學(xué)中被表示為:a+bi,其中a被稱為實(shí)部,b被稱為虛部,i被稱為虛數(shù)單位。復(fù)數(shù)在數(shù)學(xué)、理論物理學(xué)和電氣工程等方面應(yīng)用廣泛,例如向量就可以使用復(fù)數(shù)表示。
布爾類型
Python中數(shù)據(jù)類型轉(zhuǎn)換很靈活,任何類型的數(shù)據(jù)都可以通過bool()函數(shù)轉(zhuǎn)換為布爾值,那么被認(rèn)為是“空的”,“沒有的”值被轉(zhuǎn)換為False,反之,被轉(zhuǎn)換為True。
數(shù)字類型的相互轉(zhuǎn)換
Python中的很多數(shù)據(jù)類型都可以相互轉(zhuǎn)換,但是具體情況比較復(fù)雜,本章重點(diǎn)介紹數(shù)字類型之間的相互轉(zhuǎn)換。
在Python的數(shù)字類型中,除復(fù)數(shù)外,其他三種數(shù)字類型如整數(shù)、浮點(diǎn)和布爾都可以相互轉(zhuǎn)換,分為隱式類型的轉(zhuǎn)換和顯式類型的轉(zhuǎn)換。
隱式類型轉(zhuǎn)換
數(shù)字之間可以進(jìn)行數(shù)學(xué)計(jì)算,在進(jìn)行數(shù)學(xué)計(jì)算時(shí)若數(shù)字類型不同,則會發(fā)生隱式類型的轉(zhuǎn)換。
顯示類型轉(zhuǎn)換
但是請注意,復(fù)數(shù)不能和浮點(diǎn)數(shù)、整型相互轉(zhuǎn)換
03運(yùn)算符
算術(shù)運(yùn)算符
算術(shù)運(yùn)算符用于組織整數(shù)類型和浮點(diǎn)類型的數(shù)據(jù),有一元運(yùn)算符和二元運(yùn)算符之分。
一元算術(shù)運(yùn)算符有兩個(gè):+(正號)和-(負(fù)號),例如:+a還是a,-a是對a的取反運(yùn)算。
二元運(yùn)算符如下圖所示:
比較運(yùn)算符
比較運(yùn)算符用于比較兩個(gè)表達(dá)式的大小,其結(jié)果是布爾類型的數(shù)據(jù),即True或False。
比較運(yùn)算符可用于任意類型的數(shù)據(jù),但參與比較的兩種類型的數(shù)據(jù)要相互兼容,即能夠進(jìn)行隱形轉(zhuǎn)換。例如,整數(shù)、浮點(diǎn)和布爾這三種類型是相互兼容的。
位運(yùn)算符
下面是關(guān)于按位取反運(yùn)算的總結(jié):
公式~a = - (a +1)
賦值運(yùn)算符
運(yùn)算符的優(yōu)先級???
優(yōu)先級:從上到下依次降低,同一行有相同的優(yōu)先級
優(yōu)先級:括號 》冪 》位反 》正負(fù)號 》乘除取余地板除 》加減 》位移 》位與 》位異或 》 位或 》 比較 》邏輯非 》邏輯與、邏輯或
總而言之:在位運(yùn)算優(yōu)先級中,優(yōu)先級從高到低大體是:算術(shù)運(yùn)算符 →位運(yùn)算符→關(guān)系運(yùn)算符→邏輯運(yùn)算符→賦值運(yùn)算符
04程序流程控制
分支語句
python中沒有switch語句,多分支功能通過if-elif-else實(shí)現(xiàn)。
if結(jié)構(gòu)
if結(jié)構(gòu)的語法如下:
程序舉例:
score= int( input("請輸入一個(gè)0~100的整數(shù):"))if score >= 85:print("您真優(yōu)秀") if score < 60 :print("您需要加倍努力") if(score >= 60) and (score < 85) :print("您的成績還可以,仍需繼續(xù)努力")if-else結(jié)構(gòu)
程序舉例:
if-elif-else結(jié)構(gòu)
程序舉例:
循環(huán)語句
while語句
在python中只有while語句,沒有do-while語句。while語句先判斷循環(huán)條件,若條件為True則執(zhí)行循環(huán)體。
測試代碼
i = 0while i * i < 1000 :i +=1print("i = " + str(i)) print("i * i =" + str(i * i))測試結(jié)果
else子句的作用是什么呢?
else子句是在循環(huán)體正常結(jié)束時(shí)才執(zhí)行,當(dāng)中斷時(shí)不執(zhí)行。
程序測試:
i = 0while i * i < 10 :i +=1print(str(i) + '*' + str(i) + ' =' , i*i) else :print("While Over!")
修改代碼之后:
通過對比:由于后面break,所以else子句沒有運(yùn)行。
for語句
for語句的一般格式:
注 : 可迭代對象包括字符串、列表、元組、集合和字典等。
測試代碼
print("-----字符串------") for item in 'Hello' :print( item)# 聲明整數(shù)列表numbers = [43,32,55,74] print(" -----整數(shù)列表-----") for item in numbers :print(item)測試結(jié)果
for循環(huán)中的else子句也是和while中功能相同,如果循環(huán)正常結(jié)束,沒有break、return和異常發(fā)生時(shí)就執(zhí)行。
程序測試:else子句不運(yùn)行,因?yàn)閎reak執(zhí)行
for item in range(10) :if( item == 4):breakprint(item) else :print("For Overs!")05容器類型的數(shù)據(jù)
若我們想將多個(gè)數(shù)據(jù)打包并且統(tǒng)一管理,應(yīng)該怎么辦?
Python內(nèi)置的數(shù)據(jù)類型如序列(列表、元組等)、集合和字典等可以容納多項(xiàng)數(shù)據(jù),我們稱它們?yōu)槿萜黝愋偷臄?shù)據(jù)。
序列
序列(sequence)是一種可迭代的、元素有序的容器類型的數(shù)據(jù)。
序列的索引操作
序列中的元素都是有序的,每一個(gè)元素都帶有序號,這個(gè)序號叫作索引。索引有正值索引和負(fù)值索引之分。
我們是通過下標(biāo)運(yùn)算符訪問序列中的元素的,下標(biāo)運(yùn)算符是跟在容器數(shù)據(jù)后的一對中括號([]),中括號帶有參數(shù),對于序列類型的數(shù)據(jù),這個(gè)參數(shù)就是元素的索引序號。
加和 乘操作
加(+)和乘( *)運(yùn)算符也可以用于序列中的元素操作。加(+)運(yùn)算符可以將兩個(gè)序列連接起來,乘( *)運(yùn)算符可以將兩個(gè)序列重復(fù)多次。
切片操作
序列的切片(Slicing)就是從序列中切分出小的子序列。
切片運(yùn)算符的語法形式為[start:end:step]。其中,start是開始索引,end是結(jié)束索引,step是步長(切片時(shí)獲取的元素的間隔,可以為正整數(shù),也可以為負(fù)整數(shù))。
注意:切下的小切片包括start位置的元素,但不包括end位置的元素,start和end都可以省略。
下面對字符串變量a進(jìn)行切片操作[1:3],開始索引為1,結(jié)束索引為3,省略步長(默認(rèn)值為1)。
下面對字符串變量a進(jìn)行切片操作[0:3:2],開始索引為0,結(jié)束索引為3,步長為2。
成員測試
成員測試運(yùn)算符有兩個(gè):in和not in,in用于測試是否包含某一個(gè)元素,not in用于測試是否不包含某一個(gè)元素。
列表
列表(list)是一種可變序列類型,我們可以追加、插入、刪除和替換列表中的元素。
創(chuàng)建列表
1 list(iterable)函數(shù):參數(shù)iterable是可迭代對象(字符串、列表、元組、集合和字典等)。
2 [元素1,元素2,元素3,?]:指定具體的列表元素,元素之間以逗號分隔,列表元素需要使用中括號括起來。
追加元素
列表是可變的序列對象,列表可以追加元素。
1 在列表中追加單個(gè)元素時(shí),可以使用列表的append(x)方法。
2 在列表中追加多個(gè)元素時(shí),可以使用加(+)運(yùn)算符或列表的extend(t)方法
插入元素
想向列表中插入元素時(shí),可以使用列表的list.insert(i,x)方法,其中,i指定索引位置,x是要插入的元素。
替換元素
想替換列表中的元素時(shí),將列表下標(biāo)索引元素放在賦值符號(=)的左邊,進(jìn)行賦值即可。
刪除元素
想在列表中刪除元素時(shí),可使用列表的list.remove(x)方法,如果找到匹配的元素x,則刪除該元素,如果找到多個(gè)匹配的元素,則只刪除第一個(gè)匹配的元素。
元組
元組(tuple)是一種不可變序列類型。
創(chuàng)建元組
創(chuàng)建元組時(shí)有兩種方法。
1 tuple(iterable)函數(shù):參數(shù)iterable是可迭代對象(字符串、列表、元組、集合和字典等)。
2 (元素1,元素2,元素3,?):指定具體的元組元素,元素之間以逗號分隔。對于元組元素,可以使用小括號括起來,也可以省略小括號。
元組拆包
創(chuàng)建元組,并將多個(gè)數(shù)據(jù)放到元組中,這個(gè)過程被稱為元組打包。
與元組打包相反的操作是拆包,就是將元組中的元素取出,分別賦值給不同的變量。
集合
集合(set)是一種可迭代的、無序的、不能包含重復(fù)元素的容器類型的數(shù)據(jù)。
創(chuàng)建集合
我們可以通過以下兩種方式創(chuàng)建集合。
1 set(iterable)函數(shù):參數(shù)iterable是可迭代對象(字符串、列表、元組、集合和字典等)。
2 {元素1,元素2,元素3,?}:指定具體的集合元素,元素之間以逗號分隔。對于集合元素,需要使用大括號括起來。
修改集合
修改集合類似于修改列表,可以向其中插入和刪除元素。修改可變集合有如下所示的常用方法。
add(elem):添加元素,如果元素已經(jīng)存在,則不能添加,不會拋出錯(cuò)誤。
remove(elem):刪除元素,如果元素不存在,則拋出錯(cuò)誤。
clear():清除集合。
字典
字典(dict)是可迭代的、通過鍵(key)來訪問元素的可變的容器類型的數(shù)據(jù)。
字典由兩部分視圖構(gòu)成:鍵視圖和值視圖。鍵視圖不能包含重復(fù)的元素,值視圖能。在鍵視圖中,鍵和值是成對出現(xiàn)的。
創(chuàng)建字典
我們可以通過以下兩種方法創(chuàng)建字典。
1 dict()函數(shù)。
2 {key1:value1,key2:value2,…,key_n:value_n}:指定具體的字典鍵值對,鍵值對之間以逗號分隔,最后用大括號括起來。
修改字典
字典可以被修改,但都是針對鍵和值同時(shí)操作的,對字典的修改包括添加、替換和刪除。
訪問字典視圖
我們可以通過字典中的三種方法訪問字典視圖。
items():返回字典的所有鍵值對視圖。
keys():返回字典鍵視圖。
values():返回字典值視圖。
遍歷字典
測試結(jié)果
s_dict ={1 :'lishizheng' ,2 : 'lili' ,3 : 'shenglong'}print('---遍歷鍵---') for s_id in s_dict.keys() :print('學(xué)號: ' + str(s_id))print('---遍歷值---') for s_name in s_dict.values():print("姓名:"+str(s_name))print('---遍歷鍵值---') for s_id,s_name in s_dict.items():print('學(xué)號: {0} - 學(xué)生:{1}'.format(s_id,s_name))06字符串
字符串的表示方式
字符串有三種表示方式:普通字符串、原始字符串和長字符串。
普通字符串
普通字符串指用單引號(’)或雙引號(")括起來的字符串。
常見的轉(zhuǎn)義字符
原始字符串
原始字符串中的特殊字符不需要被轉(zhuǎn)義,按照字符串本來的樣子呈現(xiàn)。在普通字符串前加r就是原始字符串了。
長字符串
如果要使用字符串表示一篇文章,其中包含了換行、縮進(jìn)等排版字符,則可以使用長字符串表示。對于長字符串,要使用三個(gè)單引號(’’’)或三個(gè)雙引號(""")括起來。
字符串與數(shù)字之間的相互轉(zhuǎn)換
將字符串轉(zhuǎn)換為數(shù)字
將字符串轉(zhuǎn)換為數(shù)字,可以使用int()和float()實(shí)現(xiàn),如果成功則返回?cái)?shù)字,否則引發(fā)異常。
在默認(rèn)情況下,int()函數(shù)都將字符串參數(shù)當(dāng)作十進(jìn)制數(shù)字進(jìn)行轉(zhuǎn)換,所以int(‘AB’)會失敗。int()函數(shù)也可以指定基數(shù)(進(jìn)制)。
將數(shù)字轉(zhuǎn)換為字符串
將數(shù)字轉(zhuǎn)換為字符串,可以使用str()函數(shù),str()函數(shù)可以將很多類型的數(shù)據(jù)都轉(zhuǎn)換為字符串。
格式化字符串
使用占位符
要想將表達(dá)式的計(jì)算結(jié)果插入字符串中,則需要用到占位符。對于占位符,使用一對大括號({})表示。
默認(rèn)占位符
參數(shù)序號占位符
參數(shù)名占位符
格式化控制符
在占位符中還可以有格式化控制符,對字符串的格式進(jìn)行更加精準(zhǔn)的控制。
字符串的格式化控制符及其說明如下表所示。
格式化控制符位于占位符索引或占位符名字的后面,之間用冒號分隔,語法:{參數(shù)序號:格式控制符}或{參數(shù)名:格式控制符}。
操作字符串
字符串查找
字符串的find()方法用于查找子字符串。該方法的語法為str.find(sub[,start[,end]]),表示:在索引start到end之間查找子字符串sub,如果找到,則返回最左端位置的索引;如果沒有找到,則返回-1。
字符串替換
若想進(jìn)行字符串替換,則可以使用replace()方法替換匹配的子字符串,返回值是替換之后的字符串。該方法的語法為str.replace(old,new[,count]),表示:用new子字符串替換old子字符串。count參數(shù)指定了替換old子字符串的個(gè)數(shù),如果count被省略,則替換所有old子字符串。
字符串分割
符串分割
若想進(jìn)行字符串分割,則可以使用split()方法,按照子字符串來分割字符串,返回字符串列表對象。該方法的語法為str.split(sep=None,maxsplit=-1),表示:使用sep子字符串分割字符串str。maxsplit是最大分割次數(shù),如果maxsplit被省略,則表示不限制分割次數(shù)。
統(tǒng)計(jì)英文文章中單詞出現(xiàn)的頻率
作業(yè)題
1 設(shè)有變量s=‘Pyhon’,則"{0:3}".format(s)表達(dá)式的輸出結(jié)果是()。
A.‘hon’ B.‘Pyhon’ C.‘PYTHON’ D.‘PYT’
解答:B
2 設(shè)有變量賦值s="Hello World",則以下選項(xiàng)中可以輸出"World"子字符串的是()。
A.print(s[-5:-1]) B.print(s[-5:0]) C.print(s[-4:-1]) D.print(s[-5:])
解答:D
3 在以下選項(xiàng)中可以倒置"World"字符串的是()。
A."World"[::-1] B."World"[::] C."World"[0::-1] D."World"[-1::-1]
解答:AD
語法規(guī)則是[start: end :step]
4 判斷對錯(cuò)(請?jiān)诶ㄌ杻?nèi)打√或×,√表示正確,×表示錯(cuò)誤):。
1)原始字符串是在普通字符串前加r,使用它的優(yōu)勢是:在字符串中特殊字符不需要被轉(zhuǎn)義。(yes)
2)長字符串是,使用三個(gè)單引號(’’’)或三個(gè)雙引號(""")括起來的字符串,使用它的優(yōu)勢是:在字符串中特殊字符不需要被轉(zhuǎn)義。(no)
3)將字符串轉(zhuǎn)換為數(shù)字,可以使用int()和float()函數(shù)實(shí)現(xiàn)。(yes)
4)將數(shù)字轉(zhuǎn)換為字符串,可以使用str()函數(shù)實(shí)現(xiàn)。(yes)
07函數(shù)
定義函數(shù)
自定義函數(shù)的語法格式如下:
以英文半角冒號結(jié)尾
調(diào)用函數(shù)
使用位置參數(shù)調(diào)用函數(shù)
在調(diào)用函數(shù)時(shí)傳遞的實(shí)參與定義函數(shù)時(shí)的形參順序一致,這是調(diào)用函數(shù)的基本形式。
使用關(guān)鍵字參數(shù)調(diào)用函數(shù)
在調(diào)用函數(shù)時(shí)可以采用“關(guān)鍵字=實(shí)參”的形式,其中,關(guān)鍵字的名稱就是定義函數(shù)時(shí)形參的名稱。
參數(shù)的默認(rèn)值
python中沒有函數(shù)重載的概念,而是為函數(shù)的參數(shù)提供默認(rèn)值實(shí)現(xiàn)。
def make_coffee(name = '卡布奇諾') :return "制作一杯{0}咖啡。".format(name)coffee1= make_coffee("拿鐵") coffee2 = make_coffee()print(coffee1) print(coffee2)可變參數(shù)
可變參數(shù)在參數(shù)前加*或者**符號
基于元組的可變參數(shù)(*可變參數(shù))
*可變參數(shù)在函數(shù)中被組裝成一個(gè)元組。
基于字典的可變參數(shù)(**可變參數(shù))
**可變參數(shù)在函數(shù)中被組裝成一個(gè)字典。
函數(shù)中變量的作用域
變量可以在模塊中創(chuàng)建,作用域(變量的有效范圍)是整個(gè)模塊,被稱為全局變量。變量也可以在函數(shù)中創(chuàng)建,在默認(rèn)情況下作用域是整個(gè)函數(shù),被稱為局部變量。
測試代碼
測試結(jié)果
測試代碼
測試結(jié)果:
函數(shù)類型
Python中的任意一個(gè)函數(shù)都有數(shù)據(jù)類型,這種數(shù)據(jù)類型是function,被稱為函數(shù)類型。
函數(shù)類型的數(shù)據(jù)與其他類型的數(shù)據(jù)是一樣的,任意類型的數(shù)據(jù)都可以作為函數(shù)返回值使用,還可以作為函數(shù)參數(shù)使用。因此,一個(gè)函數(shù)可以作為另一個(gè)函數(shù)返回值使用,也可以作為另一個(gè)函數(shù)參數(shù)使用。
def add(a, b) :return a +bdef sub(a, b):return a-bdef calc(opr) :if opr == '+':return addelse:return subf1 = calc('+') f2 = calc('-') print("10 + 5 ={0}".format(f1(10,5))) print("10 -5 ={0}".format(f2(10,5)))測試結(jié)果
請看下面三個(gè)函數(shù)
add()和sub()函數(shù)有兩個(gè)數(shù)字參數(shù),具有相同的函數(shù)類型。square()函數(shù)只有一個(gè)數(shù)字參數(shù),所以square()與add()、sub()函數(shù)的類型不同。
過濾函數(shù)filter()
在Python中定義了一些用于數(shù)據(jù)處理的函數(shù),如filter()和map()等。我們先介紹filter()函數(shù)。
filter()函數(shù)用于對容器中的元素進(jìn)行過濾處理。
- 參數(shù)function是一個(gè)提供過濾條件的函數(shù),返回布爾值。
- 參數(shù)iterable是容器類型的數(shù)據(jù)。
測試代碼
def f1(x):return x >50data1 = [66,15,91,28,98,50,7,80,89] filtered = filter(f1,data1) data2 = list(filtered) print(data2)映射函數(shù)map()
map()函數(shù)用于對容器中的元素進(jìn)行映射(或變換)。例如:我想將列表中的所有元素都乘以2,返回新的列表。
map函數(shù)的語法如下:
測試代碼
lambda()函數(shù)
我們之前學(xué)習(xí)的函數(shù)都是有名稱的函數(shù),例如在8.1節(jié)定義的rect_area()函數(shù),rect_area就是其函數(shù)名。我們也可以定義匿名函數(shù),匿名函數(shù)就是沒有名稱的函數(shù)。
在Python中使用lambda關(guān)鍵字定義匿名函數(shù)。lambda關(guān)鍵字定義的函數(shù)也被稱為lambda()函數(shù),定義lambda()函數(shù)的語法如下。
“參數(shù)列表”與函數(shù)的參數(shù)列表是一樣的,但不需要用小括號括起來
lambda()函數(shù)與有名稱的函數(shù)一樣,都是函數(shù)類型,所以8.6.1節(jié)的add()和sub()函數(shù)可以被lambda()函數(shù)替代。修改8.6.1節(jié)的代碼示例如下:
測試代碼
def calc(opr):if opr == '+':return lambda a ,b:(a+b)else :return lambda a, b: (a -b)f1 = calc ('+') f2 = calc('-')print("10 + 5 = {0}".format(f1(10,5)))測試代碼
data1 = [66,14,91,28,98,50,7,80,99]filtered = filter(lambda x : (x > 50) ,data1) data2 = list(filtered) print(data2)mapped = map(lambda x :(x *2) ,data1) data3 = list(mapped) print(data3)08類與對象
面向?qū)ο?br /> 類和對象都是面向?qū)ο笾械闹匾拍睢C嫦驅(qū)ο笫且环N編程思想,即按照真實(shí)世界的思維方式構(gòu)建軟件系統(tǒng)。
例如,在真實(shí)世界的校園里有學(xué)生和老師,學(xué)生有學(xué)號、姓名、所在班級等屬性(數(shù)據(jù)),還有學(xué)習(xí)、提問、吃飯和走路等動作(方法)。如果我們要開發(fā)一個(gè)校園管理系統(tǒng),那么在構(gòu)建軟件系統(tǒng)時(shí),也會有學(xué)生和老師等“類”,張同學(xué)、李同學(xué)是學(xué)生類的個(gè)體,被稱為“對象”,“對象”也被稱為“實(shí)例”。
定義類
Python中的數(shù)據(jù)類型都是類,我們可以自定義類,即創(chuàng)建一種新的數(shù)據(jù)類型。Python中類的定義語法格式如右圖所示。
定義小汽車(Car)類的代碼如下:
小汽車(Car)類繼承了object類,object類是所有類的根類,在Python中任何一個(gè)類(除object外)都直接或間接地繼承了object,直接繼承object時(shí)(object)部分的代碼可以省略。
創(chuàng)建對象
類相當(dāng)于一個(gè)模板,依據(jù)這樣的模板來創(chuàng)建對象,就是類的實(shí)例化,所以對象也被稱為“實(shí)例”。
類的成員
成員變量也被稱為數(shù)據(jù)成員,保存了類或?qū)ο蟮臄?shù)據(jù)。例如,學(xué)生的姓名和學(xué)號。
構(gòu)造方法是一種特殊的函數(shù),用于初始化類的成員變量。
成員方法是在類中定義的函數(shù)。
屬性是對類進(jìn)行封裝而提供的特殊方法。
實(shí)例變量
實(shí)例變量就是對象個(gè)體特有的“數(shù)據(jù)”,例如狗狗的名稱和年齡等。
測試代碼
測試結(jié)果
構(gòu)造方法
類中的__init__()方法是一個(gè)非常特殊的方法,用來創(chuàng)建和初始化實(shí)例變量,這種方法就是“構(gòu)造方法”。在定義__init__()方法時(shí),它的第1個(gè)參數(shù)應(yīng)該是self,之后的參數(shù)用來初始化實(shí)例變量。調(diào)用構(gòu)造方法時(shí)不需要傳入self參數(shù)。
測試代碼
class Dog:def __init__(self, name, age):self.name = nameself.age = aged = Dog('球球', 2) d1 = Dog('花花',3) print("我們家狗狗名叫{0},{1}歲了".format(d.name ,d.age)) print("我們家的狗狗名叫{0},{1}歲了".format(d1.name , d1.age))
實(shí)例方法
實(shí)例方法與實(shí)例變量一樣,都是某個(gè)實(shí)例(或?qū)ο?#xff09;個(gè)體特有的方法。
定義實(shí)例方法時(shí),它的第1個(gè)參數(shù)也應(yīng)該是self,這會將當(dāng)前實(shí)例與該方法綁定起來,這也說明該方法屬于實(shí)例。在調(diào)用方法時(shí)不需要傳入self,類似于構(gòu)造方法。
測試代碼
測試結(jié)果
類變量
類變量是屬于類的變量,不屬于單個(gè)對象。
例如,有一個(gè)Account(銀行賬戶)類,它有三個(gè)成員變量:amount(賬戶金額)、interest_rate (利率)和owner(賬戶名)。amount和owner對于每一個(gè)賬戶都是不同的,而interest_rate對于所有賬戶都是相同的。amount和owners是實(shí)例變量,interest_rate是所有賬戶實(shí)例共享的變量,它屬于類,被稱為“類變量”。
測試代碼
測試結(jié)果
類方法
類方法與類變量類似,屬于類,不屬于個(gè)體實(shí)例。在定義類方法時(shí),它的第1個(gè)參數(shù)不是self,而是類本身。
測試代碼
class Account:interest_rate = 0.0568def __init__(self, owner, amount):self.owner = ownerself.amount = amount@classmethoddef interest_by(cls, amt):return cls.interest_rate *amtaccount = Account('Tony',800000.0)print("賬戶名:{0}".format(account.owner)) print("賬戶金額:{0}".format(account.amount)) print("利率:{0}".format(Account.interest_rate))interest = Account.interest_by(12000.0) print("計(jì)算利息:{0:.4f}".format(interest))測試結(jié)果
封裝性
封裝性是面向?qū)ο笾匾幕咎匦灾?。封裝隱藏了對象的內(nèi)部細(xì)節(jié),只保留有限的對外接口,外部調(diào)用者不用關(guān)心對象的內(nèi)部細(xì)節(jié),使得操作對象變得簡單。
例如,一臺計(jì)算機(jī)內(nèi)部極其復(fù)雜,有主板、CPU、硬盤和內(nèi)存等,而一般人不需要了解它的內(nèi)部細(xì)節(jié)。計(jì)算機(jī)制造商用機(jī)箱把計(jì)算機(jī)封裝起來,對外提供了一些接口,如鼠標(biāo)、鍵盤和顯示器等,使用計(jì)算機(jī)就變得非常簡單。
私有變量
為了防止外部調(diào)用者隨意存取類的內(nèi)部數(shù)據(jù)(成員變量),內(nèi)部數(shù)據(jù)(成員變量)會被封裝為“私有變量”。外部調(diào)用者只能通過方法調(diào)用私有變量。
在默認(rèn)情況下,Python中的變量是公有的,可以在類的外部訪問它們。如果想讓它們成為私有變量,則在變量前加上雙下畫線(__)即可。
由于在類的外部不可以訪問私有變量,因此上述代碼在運(yùn)行時(shí)會發(fā)生錯(cuò)誤,通過Python指令運(yùn)行文件,輸出結(jié)果。
測試代碼
class Account:__interest_rate = 0.0568 # 類變量利率def __init__(self, owner, amount):self.owner = ownerself.__amount = amountdef desc(self):print("{0} 金額:{1} 利率: {2}".format(self.owner,self.__amount,Account.__interest_rate))@classmethoddef interest_by(cls, amt):return cls.interest_rate *amtaccount = Account('Tony',800000.0) account.desc()print("賬戶名:{0}".format(account.owner)) print("賬戶金額:{0}".format(account.__amount)) print("利率:{0}".format(Account.__interest_rate))測試結(jié)果
私有方法
私有方法與私有變量的封裝是類似的,在方法前加上雙下畫線(__)就是私有方法了。示例代碼如下:
測試代碼
class Account:__interest_rate = 0.0568 # 類變量利率def __init__(self, owner, amount):self.owner = ownerself.__amount = amountdef __get_info(self):return "{0} 金額: {1} 利率:{2}".format(self.owner,self.__amount,Account.__interest_rate)def desc(self):print(self.__get_info())@classmethoddef interest_by(cls, amt):return cls.interest_rate *amtaccount = Account('Tony',800000.0) account.desc()account.__get_info()測試結(jié)果
使用屬性
為了實(shí)現(xiàn)對象的封裝,在一個(gè)類中不應(yīng)該有公有的成員變量,這些成員變量應(yīng)該被設(shè)計(jì)為私有的,然后通過公有的set(賦值)和get(取值)方法訪問。
使用set和get方法進(jìn)行封裝,示例代碼如下:
測試代碼
測試結(jié)果
測試代碼
測試結(jié)果
繼承性
繼承性也是面向?qū)ο笾匾幕咎匦灾弧?br /> 在現(xiàn)實(shí)世界中繼承關(guān)系無處不在。例如貓與動物之間的關(guān)系:貓是一種特殊動物,具有動物的全部特征和行為,即數(shù)據(jù)和操作。在面向?qū)ο笾袆游锸且话泐?#xff0c;被稱為“父類”;貓是特殊類,被稱為“子類”。特殊類擁有一般類的全部數(shù)據(jù)和操作,可稱之為子類繼承父類。
在Python中聲明子類繼承父類,語法很簡單,定義類時(shí)在類的后面使用一對小括號指定它的父類就可以了。
測試代碼
測試結(jié)果
多繼承
在Python中,當(dāng)子類繼承多個(gè)父類時(shí),如果在多個(gè)父類中有相同的成員方法或成員變量,則子類優(yōu)先繼承左邊父類中的成員方法或成員變量,從左到右繼承級別從高到低。
方法重寫
如果子類的方法名與父類的方法名相同,則在這種情況下,子類的方法會重寫(Override)父類的同名方法
多態(tài)性
多態(tài)性也是面向?qū)ο笾匾幕咎匦灾??!岸鄳B(tài)”指對象可以表現(xiàn)出多種形態(tài)。
例如,貓、狗、鴨子都屬于動物,它們有“叫”和“動”等行為,但是叫的方式不同,動的方式也不同。
繼承與多態(tài)
在多個(gè)子類繼承父類,并重寫父類方法后,這些子類所創(chuàng)建的對象之間就是多態(tài)的。這些對象采用不同的方式實(shí)現(xiàn)父類方法。
測試代碼
測試結(jié)果
09異常處理
為增強(qiáng)程序的健壯性,我們也需要考慮異常處理方面的內(nèi)容。例如,在讀取文件時(shí)需要考慮文件不存在、文件格式不正確等異常情況。這就是本章要介紹的異常處理。
測試代碼
測試結(jié)果
捕獲異常
我們不能防止用戶輸入0,但在出現(xiàn)異常后我們能捕獲并處理異常,不至于讓程序發(fā)生終止并退出。亡羊補(bǔ)牢,為時(shí)未晚。
try-except語句
常捕獲是通過try-except語句實(shí)現(xiàn)的,基本的try-except語句的語法如下。
在try代碼塊中包含在執(zhí)行過程中可能引發(fā)異常的語句,如果發(fā)生異常,則跳到except代碼塊執(zhí)行,這就是異常捕獲。
測試代碼
測試結(jié)果
測試代碼
i = input('請輸入數(shù)字:')n = 8888try :result = n / int(i)print(result)print('{0}除以{1}等于{2}'.format(n,i,result)) except ZeroDivisionError as e:print('不能除以零,異常:{}'.format(e))測試結(jié)果
從運(yùn)行的結(jié)果可以看出,在輸入數(shù)字0后,異常發(fā)生,跳到except代碼塊執(zhí)行。
多個(gè)except代碼塊
多條語句可能會引發(fā)多種不同的異常,對每一種異常都會采用不同的處理方式。針對這種情況,我們可以在一個(gè)try后面跟多個(gè)except代碼塊,語法如下
測試代碼
i = input('請輸入數(shù)字:')n = 8888try :result = n / int(i)print(result)print('{0}除以{1}等于{2}'.format(n,i,result)) except ZeroDivisionError as e:print('不能除以零,異常:{}'.format(e)) except ValueError as e:print("輸入的是無效數(shù)字,異常:{}".format(e))測試結(jié)果
多重異常捕獲
測試代碼
i = input('請輸入數(shù)字:')n = 8888try :result = n / int(i)print(result)print('{0}除以{1}等于{2}'.format(n,i,result)) except ( ZeroDivisionError, ValueError ) as e:print('異常:{}'.format(e))測試結(jié)果
try-except語句嵌套
測試代碼
測試結(jié)果
使用finally代碼塊釋放資源
有時(shí)在try-except語句中會占用一些資源,例如打開的文件、網(wǎng)絡(luò)連接、打開的數(shù)據(jù)庫及數(shù)據(jù)結(jié)果集等都會占用計(jì)算機(jī)資源,需要程序員釋放這些資源。為了確保這些資源能夠被釋放,可以使用finally代碼塊。
在try-except語句后面還可以跟一個(gè)finally代碼塊,語法如下。
無論是try代碼塊正常結(jié)束還是except代碼塊異常結(jié)束,都會執(zhí)行finally代碼塊。
自定義異常類
10常用的內(nèi)置模塊
在真正做項(xiàng)目時(shí),我們會使用別人已經(jīng)開發(fā)好的模塊,這樣就不必從零開發(fā)項(xiàng)目了,還可以加快開發(fā)速度。這些模塊可能是Python官方提供的,也可能是第三方開發(fā)的。Python官方提供的模塊,就叫作“內(nèi)置模塊”。
數(shù)學(xué)計(jì)算模塊
在math模塊中包含數(shù)學(xué)運(yùn)算相關(guān)的函數(shù)等,例如指數(shù)、對數(shù)、平方根和三角函數(shù)等。

日期時(shí)間模塊
Python官方提供的日期和時(shí)間模塊主要是datetime模塊。在datetime模塊中提供了右側(cè)幾個(gè)類。
- datetime:包含時(shí)間和日期。
- date:只包含日期。
- time:只包含時(shí)間。
- timedelta:計(jì)算時(shí)間跨度。
- tzinfo:時(shí)區(qū)信息。
datetime類
datetime類表示日期和時(shí)間等信息,我們可以使用如下構(gòu)造方法創(chuàng)建datetime對象:
對這些參數(shù)的說明如下表所示
datetime類的常用方法如下。
datetime.today():返回當(dāng)前的本地日期和時(shí)間。
datetime.now(tz=None):返回指定時(shí)區(qū)的當(dāng)前日期和時(shí)間,參數(shù)tz用于設(shè)置時(shí)區(qū),如果參數(shù)tz為None或省略,則等同于today()。
datetime.fromtimestamp(timestamp,tz=None):返回與UNIX時(shí)間戳對應(yīng)的本地日期和時(shí)間。UNIX時(shí)間戳是從1970年1月1日00:00:00開始到現(xiàn)在為止的總秒數(shù)。
date類
date類表示日期信息,我們可以使用如下構(gòu)造方法創(chuàng)建date對象:
這些參數(shù)的含義和取值范圍與datetime類一樣,這里不再贅述。
date類的常用方法如下。
date.today():返回當(dāng)前的本地日期。
date.fromtimestamp(timestamp):返回與UNIX時(shí)間戳對應(yīng)的本地日期。
time類
time類表示一天中的時(shí)間信息,我們可以使用如下構(gòu)造方法創(chuàng)建time對象:
計(jì)算時(shí)間跨度類(timedelta)
參數(shù)說明
timedelta可以表示正數(shù)或負(fù)數(shù)時(shí)間的間隔,如下代碼是等效的
將日期時(shí)間與字符串相互轉(zhuǎn)換
我們經(jīng)常會遇到將日期時(shí)間與字符串相互轉(zhuǎn)換的情況。
1 將日期時(shí)間對象轉(zhuǎn)換為字符串時(shí),稱之為日期時(shí)間格式化。
在Python中使用strftime()方法進(jìn)行日期時(shí)間的格式化,在datetime、date和time三個(gè)類中都有一個(gè)實(shí)例方法strftime(format)。
2 將字符串轉(zhuǎn)換為日期時(shí)間對象的過程,叫作日期時(shí)間解析。
在Python中使用datetime.strptime(date_string,format)類方法進(jìn)行日期時(shí)間解析。
在strftime()和strptime()方法中都有一個(gè)格式化參數(shù)format,用來控制日期時(shí)間的格式,常用的日期和時(shí)間格式控制符如下表所示。
正則表達(dá)式模塊(re)
正則表達(dá)式指預(yù)先定義好一個(gè)“字符串模板”,通過這個(gè)“字符串模板”可以匹配、查找和替換那些匹配“字符串模板”的字符串。
字符串匹配
字符串匹配指驗(yàn)證一個(gè)字符串是否符合指定的“字符串模板”,常用于用戶輸入驗(yàn)證。例如,用戶在注冊時(shí)要輸入郵箱,所以需要驗(yàn)證郵箱是否有效,這就要用到字符串匹配驗(yàn)證。
我們使用match(p,text)函數(shù)進(jìn)行字符串匹配,其中的參數(shù)p是正則表達(dá)式,即字符串模板,text是要驗(yàn)證的字符串。如果匹配成功,則返回一個(gè)Match對象(匹配對象),否則返回None。
字符串查找
字符串查找指從一個(gè)字符串中查找匹配正則表達(dá)式的子字符串,常用于數(shù)據(jù)分析、網(wǎng)絡(luò)爬蟲等數(shù)據(jù)處理中。
常用的字符串查找函數(shù)如下。
search(p,text):在text字符串中查找匹配的內(nèi)容,如果找到,則返回第1個(gè)匹配的Match對象,否則返回None。p是正則表達(dá)式。
findall(p,text):在text字符串中查找所有匹配的內(nèi)容,如果找到,則返回所有匹配的字符串列表;如果一個(gè)都沒有匹配,則返回None。p是正則表達(dá)式。
測試代碼
字符串替換
正則表達(dá)式的字符串替換函數(shù)是sub(),該函數(shù)替換匹配的子字符串,返回值是替換之后的字符串,其語法格式如下:
其中,參數(shù)pattern是正則表達(dá)式;參數(shù)repl是用于替換的新字符串;參數(shù)string是即將被替換的舊字符串;參數(shù)count是要替換的最大數(shù)量,默認(rèn)值為零,表示不限制替換數(shù)量。
字符串分割
在Python中使用re模塊中的split()函數(shù)進(jìn)行字符串分割,該函數(shù)按照匹配的子字符串進(jìn)行字符串分割,返回字符串列表對象,其語法格式如下:
其中,參數(shù)pattern是正則表達(dá)式;參數(shù)string是要分割的字符串;參數(shù)maxsplit是最大分割次數(shù);maxsplit的默認(rèn)值為零,表示分割次數(shù)沒有限制。
如何使用官方文檔查找模塊幫助信息?
打開官方幫助文檔
11文件讀寫
文件是數(shù)據(jù)的載體,程序可以從文件中讀取數(shù)據(jù),也可以將數(shù)據(jù)寫入文件中,本章重點(diǎn)介紹如何在Python中進(jìn)行文件讀寫。
打開文件
我們在使用文件之前要先將文件打開,這通過open()函數(shù)實(shí)現(xiàn)。open()函數(shù)的語法如下:
open()函數(shù)中的參數(shù)還有很多,這里介紹4個(gè)常用參數(shù),這些參數(shù)的含義如下。
1.file參數(shù)
file參數(shù)用于表示要打開的文件,可以是字符串或整數(shù)。如果file是字符串,則表示文件名,文件名既可以是當(dāng)前目錄的相對路徑,也可以是絕對路徑;如果file是整數(shù),則表示一個(gè)已經(jīng)打開的文件。
2.mode參數(shù)
mode參數(shù)用于設(shè)置文件打開模式,用字符串表示,例如rb表示以只讀模式打開二進(jìn)制文件。用于設(shè)置文件打開模式的字符串中的每一個(gè)字符都表示不同的含義,對這些字符的具體說明如下。
- t:以文本文件模式打開文件。
- b:以二進(jìn)制文件模式打開文件。
- r:以只讀模式打開文件。
- w:以只寫模式打開文件,不能讀內(nèi)容。如果文件不存在,則創(chuàng)建文件;如果文件存在,則覆蓋文件的內(nèi)容。
- x:以獨(dú)占創(chuàng)建模式打開文件,如果文件不存在,則創(chuàng)建并以寫入模式打開;如果文件已存在,則引發(fā)FileExistsError異常。
- a:以追加模式打開文件,不能讀內(nèi)容。如果文件不存在,則創(chuàng)建文件;如果文件存在,則在文件末尾追加。
- +:以更新(讀寫)模式打開文件,必須與r、w或a組合使用,才能設(shè)置文件為讀寫模式。
這些字符可以進(jìn)行組合,以表示不同類型的文件的打開模式,如下表所示。
3.encoding參數(shù)
encoding用來指定打開文件時(shí)的文件編碼,默認(rèn)是UTF-8編碼,主要用于打開文本文件。
4.errors參數(shù)
errors參數(shù)用來指定在文本文件發(fā)生編碼錯(cuò)誤時(shí)如何處理。推薦errors參數(shù)的取值為’ignore’,表示在遇到編碼錯(cuò)誤時(shí)忽略該錯(cuò)誤,程序會繼續(xù)執(zhí)行,不會退出。
測試代碼
f = open('test.txt','w+') f.write('World') print('創(chuàng)建test.txt文件,World寫入文件')f = open('test.txt', 'r+') f.write('Hello') print('打開test.txt文件,Hello覆蓋文件內(nèi)容')f= open('test.txt','a') f.write(' ') print("打開test.txt文件,在文件尾部追加空格")fname =r'D:\user\文檔\python\12文件讀寫\test.txt' f= open(fname, 'a+') f.write('World') print('打開test.txt文件,在文件尾部追加World')測試結(jié)果
關(guān)閉文件
在打開文件后,如果不再使用該文件,則應(yīng)該將其關(guān)閉,會用到close()方法。
在finally代碼塊中關(guān)閉文件
對文件的操作往往會拋出異常,為了保證對文件的操作無論是正常結(jié)束還異常結(jié)束,都能夠關(guān)閉文件,我們應(yīng)該將對close()方法的調(diào)用放在異常處理的finally代碼塊中。
測試代碼
f_name = 'test.txt' f =None try:f =open(f_name)print('打開文件成功')content = f.read()print(content)except FileNotFoundError as e:print('文件不存在,請先創(chuàng)建文件') except OSError as e:print('處理OSError異常') finally:if f is not None:f.close()print('關(guān)閉文件成功')測試結(jié)果
在with as代碼塊中關(guān)閉文件
測試代碼
測試結(jié)果
with as提供了一個(gè)代碼塊,在as后面聲明一個(gè)資源變量,在with as代碼塊結(jié)束之后自動釋放資源。
讀寫文本文件
讀寫文本文件的相關(guān)方法如下。
- read(size=-1):
從文件中讀取字符串,size限制讀取的字符數(shù),size=-1指對讀取的字符數(shù)沒有限制。 - readline(size=-1):
在讀取到換行符或文件尾時(shí)返回單行字符串。如果已經(jīng)到文件尾,則返回一個(gè)空字符串。size是限制讀取的字符數(shù),size=-1表示沒有限制。 - readlines():
讀取文件數(shù)據(jù)到一個(gè)字符串列表中,每一行數(shù)據(jù)都是列表的一個(gè)元素。 - write(s):
將字符串s寫入文件中,并返回寫入的字符數(shù)。 - writelines(lines):
向文件中寫入一個(gè)字符串列表。不添加行分隔符,因此通常為每一行末尾都提供行分隔符。 - flush():
刷新寫緩沖區(qū),在文件沒有關(guān)閉的情況下將數(shù)據(jù)寫入文件中。
復(fù)制文本文件
測試代碼
f_name ='src_file.txt'with open(f_name, 'r', encoding ='gbk' ) as f:lines = f.readlines()copy_f_name ='dest_file.txt'with open(copy_f_name, 'w',encoding ='utf-8') as copy_f:copy_f.writelines(lines)print('文件復(fù)制成功')測試結(jié)果(不對)
原因是scr_file.txt文件需要設(shè)置成ANSI
正確的測試結(jié)果
讀寫二進(jìn)制文件
二進(jìn)制文件的讀寫單位是字節(jié),不需要考慮編碼問題。二進(jìn)制文件的主要讀寫方法如下。
- read(size=-1):從文件中讀取字節(jié),size限制讀取的字節(jié)數(shù),如果size=-1,則讀取全部字節(jié)。
- readline(size=-1):從文件中讀取并返回一行。size是限制讀取的行數(shù),如果size=-1,則沒有限制。
- readlines():讀取文件數(shù)據(jù)到一個(gè)字節(jié)列表中,每一行數(shù)據(jù)都是列表的一個(gè)元素。
- write(b):寫入b字節(jié),并返回寫入的字節(jié)數(shù)。
- writelines(lines):向文件中寫入一個(gè)字節(jié)列表。不添加行分隔符,因此通常為每一行末尾都提供行分隔符。
- flush():刷新寫緩沖區(qū),在文件沒有關(guān)閉的情況下將數(shù)據(jù)寫入文件中。
測試代碼
f_name = '十三邀.png'with open(f_name ,'rb') as f:b =f.read()copy_f_name = 'logo2.png'with open(copy_f_name, 'wb') as copy_f:copy_f.write(b)print('文件復(fù)制成功')測試結(jié)果
13網(wǎng)絡(luò)通信
本章講解如何通過Python訪問互聯(lián)網(wǎng)上的資源,這也是網(wǎng)絡(luò)爬蟲技術(shù)的基礎(chǔ)。
基礎(chǔ)的網(wǎng)絡(luò)知識
TCP/IP
在網(wǎng)絡(luò)通信中會用到一些相關(guān)協(xié)議,其中,TCP/IP是非常重要的協(xié)議,由IP和TCP兩個(gè)協(xié)議構(gòu)成。IP(Internet Protocol)是一種低級的路由協(xié)議,它將數(shù)據(jù)拆分在許多小的數(shù)據(jù)包中,并通過網(wǎng)絡(luò)將它們發(fā)送到某一特定地址,但無法保證所有包都抵達(dá)目的地,也不能保證包按順序抵達(dá)。
由于通過IP傳輸數(shù)據(jù)存在不安全性,所以還需要通過TCP(Transmission Control Protocol,傳輸控制協(xié)議)進(jìn)行網(wǎng)絡(luò)通信。TCP是一種高層次的協(xié)議,是面向連接的可靠數(shù)據(jù)傳輸協(xié)議,如果有些數(shù)據(jù)包沒被收到,則會重發(fā),對數(shù)據(jù)包的內(nèi)容準(zhǔn)確性進(jìn)行檢查并保證數(shù)據(jù)包按順序抵達(dá)。所以,TCP能夠保證數(shù)據(jù)包安全地按照發(fā)送時(shí)的順序送達(dá)目的地。
IP地址
為了實(shí)現(xiàn)網(wǎng)絡(luò)中不同計(jì)算機(jī)之間的通信,每臺計(jì)算機(jī)都必須有一個(gè)與眾不同的標(biāo)識,這就是IP地址,TCP/IP使用IP地址來標(biāo)識源地址和目的地址。
最初,所有的IP地址都是由32位數(shù)字構(gòu)成的,由4個(gè)8位的二進(jìn)制數(shù)組成,每8位之間用圓點(diǎn)隔開,例如192.168.1.1,這種類型的地址通過IPv4指定?,F(xiàn)在有一種新的地址模式,叫作IPv6,IPv6使用128位數(shù)字表示一個(gè)地址。盡管IPv6比IPv4有很多優(yōu)勢,但是由于習(xí)慣的問題,很多設(shè)備還是采用IPv4。
另外,我們有時(shí)還會用到一個(gè)特殊的IP地址127.0.0.1,127.0.0.1叫作回送地址,指本機(jī)。回送地址主要用于網(wǎng)絡(luò)軟件測試及本機(jī)的進(jìn)程間通信,只發(fā)送數(shù)據(jù),只進(jìn)行本機(jī)進(jìn)程間通信,不進(jìn)行任何網(wǎng)絡(luò)傳輸。
端口
一個(gè)IP地址標(biāo)識一臺計(jì)算機(jī),每一臺計(jì)算機(jī)又有很多網(wǎng)絡(luò)通信程序在運(yùn)行,提供網(wǎng)絡(luò)服務(wù)或進(jìn)行通信,這就需要不同的端口進(jìn)行通信。如果把IP地址比作電話號碼,那么端口就是分機(jī)號碼,在進(jìn)行網(wǎng)絡(luò)通信時(shí)不僅要指定IP地址,還要指定端口號
TCP/IP系統(tǒng)中的端口號是一個(gè)16位的數(shù)字,它的范圍是 0~65535。將小于1024的端口號保留給預(yù)定義的服務(wù),例如HTTP是80,FTP是21,Telnet是23,Email是25,等等。除非要和那些服務(wù)進(jìn)行通信,否則不應(yīng)該使用小于1024的端口。
HTTP/HTTPS
對互聯(lián)網(wǎng)的訪問大多基于HTTP/HTTPS,HTTP/HTTPS是TCP/IP的一種協(xié)議。
1 HTTP
HTTP(Hypertext Transfer Protocol,超文本傳輸協(xié)議)屬于應(yīng)用層協(xié)議,其簡捷、快速的方式適用于分布式超文本信息傳輸。HTTP是無連接協(xié)議,即在每一次請求時(shí)都建立連接,服務(wù)器在處理完客戶端的請求后,會先應(yīng)答客戶端,然后斷開連接,不會一直占用網(wǎng)絡(luò)資源。
HTTP/1.1共定義了8種請求方法:OPTIONS、HEAD、GET、POST、PUT、DELETE、TRACE和CONNECT。GET和POST方法最常用。
1) GET方法:用于向指定的資源發(fā)出請求,被發(fā)送的信息“顯式”地跟在URL后面。它一般只用于讀取數(shù)據(jù),例如靜態(tài)圖片等。GET方法有點(diǎn)像使用明信片給別人寫信,將“信的內(nèi)容”寫在外面,接觸到的人都可以看到,因此是不安全的。
2) POST方法:用于向指定的資源提交數(shù)據(jù),請求服務(wù)器進(jìn)行處理,例如提交表單或者上傳文件等。數(shù)據(jù)被包含在請求體中。POST方法像是把“信的內(nèi)容”裝入信封中,接觸到該信封的人都看不到信的內(nèi)容,因此是相對安全的。
2 HTTPS
HTTPS(Hypertext Transfer Protocol Secure,超文本傳輸安全協(xié)議)是超文本傳輸協(xié)議和SSL的組合,用于提供加密通信及對網(wǎng)絡(luò)服務(wù)器身份的鑒定。簡單地說,HTTPS是加密的HTTP。
HTTPS與HTTP的區(qū)別是:HTTPS使用https://代替http://,HTTPS使用端口443,而HTTP使用端口80與TCP/IP通信。
urllib.request模塊
我們要想在Python中訪問互聯(lián)網(wǎng)資源,則可以使用官方內(nèi)置的urllib.request模塊。
發(fā)送GET請求
如果要發(fā)送HTTP/HTTPS的GET請求,則可以使用urllib.request模塊的Request對象。
發(fā)送POST請求
如果要發(fā)送HTTP/HTTPS的POST請求,則其發(fā)送流程與發(fā)送GET請求非常類似。
示例代碼如下:
JSON數(shù)據(jù)
JSON文檔的結(jié)構(gòu)
構(gòu)成JSON文檔的兩種結(jié)構(gòu)為:JSON對象(object)和JSON數(shù)組(array)。
JSON數(shù)據(jù)的解碼(decode)指將JSON數(shù)據(jù)轉(zhuǎn)換為Python數(shù)據(jù),當(dāng)從網(wǎng)絡(luò)中接收或從磁盤中讀取JSON數(shù)據(jù)時(shí),需要將其解碼為Python數(shù)據(jù)。
在編碼過程中,JSON數(shù)據(jù)被轉(zhuǎn)換為Python數(shù)據(jù)
們使用json模塊提供的loads(str)函數(shù)進(jìn)行JSON數(shù)據(jù)的解碼,參數(shù)str是JSON字符串,返回Python數(shù)據(jù)。
參考資料
參考資料
[1]https://www.dedao.cn/eBook/DLnMGAEG7gKLyYmkAbPaEXxD8BM4J0LM6AWROrpdZn19VNzv2o5e6lqjQQ1poxqy
總結(jié)
以上是生活随笔為你收集整理的python入门学习[看漫画学Python:有趣、有料、好玩、好用读书笔记]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python报错TabError: in
- 下一篇: websocket python爬虫_p