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

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