一葡幸、錯誤和異常
1.概念
兩種容易辨認的錯誤
? 語法錯誤:一些關(guān)于語法的錯誤【縮進】
? 異常:代碼完全正確软驰,但是载城,程序運行之后瞧捌,會報出 的錯誤
exception/error
代碼演示:
list1 = [23,54,6,6] print(list1[2]) print(list1[3]) print(list1[4]) print("over") """ 6 6 Traceback (most recent call last): File "C:/Users/Administrator/Desktop/SZ-Python/Day15Code/textDemo01.py", line 4, in <module> print(list1[4]) IndexError: list index out of range """
異常特點:當程序在執(zhí)行的過程中遇到異常管跺,程序?qū)K止在出現(xiàn)異常的代碼處义黎,代碼不會繼續(xù)向下執(zhí)行
解決問題:越過異常,保證后面的代碼繼續(xù)執(zhí)行【實質(zhì):將異常暫時屏蔽起來豁跑,目的是為了讓后面的代碼的執(zhí)行不受影響】
2.常見的異常
NameError:變量未被定義
TypeError:類型錯誤
IndexError:索引異常
keyError:
ValueError:
AttributeError:屬性異常
ImportError:導入模塊的時候路徑異常
SyntaxError:代碼不能編譯
UnboundLocalError:試圖訪問一個還未被設(shè)置的局部變量
3.異常處理方式【掌握】
捕獲異常
拋出異常
3.1捕獲異常
try-except-else
語法:
? try:
? 可能存在異常的代碼
? except 錯誤表示碼 as 變量:
? 語句1
? except 錯誤表示碼 as 變量:
? 語句2
? 廉涕。。。
? else:
? 語句n
說明:
? a.try-except-else的用法類似于if-elif-else
? b.else可有可無狐蜕,根據(jù)具體的需求決定
? c.try后面的代碼塊被稱為監(jiān)測區(qū)域【檢測其中的代碼是否存在異澈撸】
? d.工作原理:首先執(zhí)行try中的語句,如果try中的語句沒有異常馏鹤,則直接跳過所有的except語句征椒,執(zhí)行else;如果try中的語句有異常湃累,則去except分支中進行匹配錯誤碼勃救,如果匹配到了,則執(zhí)行except后面的語句治力;如果沒有except匹配蒙秒,則異常仍然沒有被攔截【屏蔽】
代碼演示:
#一、try-except-else的使用 #1.except帶有異常類型 try: print(10 / 0) except ZeroDivisionError as e: print("被除數(shù)不能為0",e) print("~~~~") """ 總結(jié): a.try-except屏蔽了異常宵统,保證后面的代碼可以正常執(zhí)行 b.except ZeroDivisionError as e相當于聲明了一個ZeroDivisionError類型的變量【對象】晕讲,變量e中攜帶了錯誤的信息 """ #2.try后面的except語句可以有多個 class Person(object): __slots__ = ("name") try: p = Person() p.age = 19 print(10 / 0) except AttributeError as e: print("屬性異常",e) except ZeroDivisionError as e: print("被除數(shù)不能為0",e) print("over") """ 總結(jié): a.一個try語句后面可以有多個except分支 b.不管try中的代碼有多少個異常,except語句都只會被執(zhí)行其中的一個马澈,哪個異常處于try語句的前面瓢省,則先先執(zhí)行對應的except語句 c.后面的異常不會報錯【未被執(zhí)行到】 """ #3.except語句的后面可以不跟異常類型 try: print(10 / 0) except: print("被除數(shù)不能為0") #4.一個except語句的后面可以跟多種異常的類型 #注意:不同的異常類型使用元組表示 try: print(10 / 0) except (ZeroDivisionError,AttributeError): print("出現(xiàn)了異常") #5.else分支 try: print(10 / 4) except ZeroDivisionError as e: print("出現(xiàn)了異常",e) else: print("hello") """ 總結(jié): a.如果try中的代碼出現(xiàn)了 異常,則直接去匹配except痊班,else分支不會被執(zhí)行 b.如果try中的代碼沒有出現(xiàn)異常勤婚,則try中的代碼正常執(zhí)行,except不會被執(zhí)行涤伐,else分支才會被執(zhí)行 """ #6.try中不僅可以直接處理異常馒胆,還可以處理一個函數(shù)中的異常 def show(): x = 1 / 0 try: show() except: print("出現(xiàn)了異常") #7.直接使用BaseException代替所有的異常 try: y = 10 / 0 except BaseException as e: print(e) """ 總結(jié):在Python中,所有的異常其實都是類凝果,他們都有一個共同的父類BaseException祝迂,可以使用BaseException將所有異常“一網(wǎng)打盡” """
try-except-finally
語法:
? try:
? 可能存在異常的代碼
? except 錯誤表示碼 as 變量:
? 語句1
? except 錯誤表示碼 as 變量:
? 語句2
? 器净。型雳。。
? finally:
? 語句n
說明:不管try中的語句是否存在異常掌动,不管異常是否匹配到了except語句四啰,finally語句都會被執(zhí)行
作用:表示定義清理行為,表示無論什么情況下都需要進行的操作
代碼演示:
#二粗恢、try-except-finally的使用 #1. try: print(10 / 5) except ZeroDivisionError as e: print(e) finally: print("finally被執(zhí)行") #2.特殊情況 #注意:當在try或者except中出現(xiàn)return語句時柑晒,finally語句仍然會被執(zhí)行 def show(): try: print(10 / 0) return except ZeroDivisionError as e: print(e) finally: print("finally被執(zhí)行~~~~") show()
3.2拋出異常
raise拋出一個指定的異常對象
語法:raise 異常對象 或者 raise
說明:異常對象通過錯誤表示碼創(chuàng)建,一般來說錯誤表示碼越準確越好
代碼演示:
#raise的使用主要體現(xiàn)在自定義異常中 #1.raise表示直接拋出一個異常對象【異常是肯定存在的】 #創(chuàng)建對象的時候眷射,參數(shù)表示對異常信息的描述 try: raise NameError("hjafhfja") except NameError as e: print(e) print("over") """ 總結(jié): 通過raise拋出的異常匙赞,最終還是需要通過try-except處理 """ #2.如果通過raise拋出的異常在try中不想被處理佛掖,則可以通過raise直接向上拋出 try: raise NameError("hjafhfja") except NameError as e: print(e) raise
4.assert斷言
對某個問題做一個預測,如果預測成功涌庭,則獲取結(jié)果芥被;如果預測失敗,則打印預測的信息
代碼演示:
def func(num,divNum): #語法:assert表達式坐榆,當出現(xiàn)異常時的信息描述 #assert關(guān)鍵字的作用:預測表達式是否成立拴魄,如果成立,則執(zhí)行后面的代碼席镀;如果不成立匹中,則將異常的描述信息打印出來 assert (divNum != 0),"被除數(shù)不能為0" return num / divNum print(func(10,20)) print(func(10,0))
5.異常的嵌套
代碼演示:
#需求:去拉薩,乘坐各種交通工具 print("我要去拉薩") try: print("我準備乘飛機過去") raise Exception("由于大霧豪诲,飛機不能起飛") print("到拉薩了顶捷,拉薩真漂亮") except Exception as e: print(e) try: print("我準備乘火車過去") raise Exception("由于大暴雨,鐵路斷了") print("到拉薩了屎篱,拉薩真漂亮") except Exception as e: print(e) print("我準備跑過去") print("到拉薩了服赎,拉薩真漂亮")
6.自定義異常
實現(xiàn)思路:
a.定義一個類,繼承自Exception類
b.書寫構(gòu)造函數(shù)交播,屬性保存異常信息【調(diào)用父類的構(gòu)造函數(shù)】
c.重寫str函數(shù)重虑,打印異常的信息
d.定義一個成員函數(shù),用來處理自己的異常
代碼演示:
class MyException(Exception): def __init__(self,msg): super(MyException,self).__init__() self.msg = msg def __str__(self): return self.msg def handle(self): print("出現(xiàn)了異常") try: raise MyException("自己異常的類型") except MyException as e: print(e) e.handle()
二堪侯、文件讀寫
1.概念
在Python中嚎尤,通過打開文件生成一個文件對象【文件描述符】操作磁盤上的文件,操作主要由文件讀寫
2.普通文件的讀寫
普通文件包含:txt文件伍宦,圖片,視頻乏梁,音頻等
2.1讀文件
操作步驟:
? a.打開文件:open()
? b.讀取文件內(nèi)容:read()
? c.關(guān)閉文件:close()
說明:最后一定不要忘了文件關(guān)閉次洼,避免系統(tǒng)資源的浪費【因為一個文件對象會占用系統(tǒng)資源】
代碼演示:
#一、打開文件 """ open(path,flag[,encoding,errors]) path:指定文件的路徑【絕對路徑和相對路徑】 flag:打開文件的方式 r:只讀遇骑、 rb:read binary,以二進制的方式打開卖毁,只讀【圖片,視頻落萎,音頻等】 r+:讀寫 w:只能寫入 wb:以二進制的方式打開亥啦,只能寫入【圖片,視頻练链,音頻等】 w+:讀寫 a:append,如果一個文件不為空翔脱,當寫入的時候不會覆蓋掉原來的內(nèi)容 encoding:編碼格式:gbk,utf-8 errors:錯誤處理 """ path = r"C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\致橡樹.txt" #調(diào)用open函數(shù),得到了文件對象 f = open(path,"r",encoding="gbk") """ 注意: a.以r的方式打開文件時媒鼓,encoding是不是必須出現(xiàn) 如果文件格式為gbk,可以不加encoding="gbk" 如果文件格式為utf-8,必須添加encoding="utf-8" b届吁。如果打開的文件是圖片错妖,音頻或者視頻等,打開方式采用rb,但是疚沐,此時暂氯,不能添加encoding="xxx" """ #二、讀取文件內(nèi)容 #1.讀取全部內(nèi)容 *********** #str = f.read() #print(str) #2.讀取指定的字符數(shù) #注意:如果每一行的結(jié)尾有個"\n",也被識別成字符 """ str1 = f.read(2) print(str1) str1 = f.read(2) print(str1) str1 = f.read(2) print(str1) #3.讀取整行亮蛔,不管該行有多少個字符 ********* str2 = f.readline() print(str2) str2 = f.readline() print(str2) """ #4.讀取一行中的指定的字符 #str3 = f.readline(3) #print(str3) #5.讀取全部的內(nèi)容痴施,返回的結(jié)果為一個列表,每一行數(shù)據(jù)為一個元素 #注意:如果指明參數(shù)究流,則表示讀取指定個數(shù)的字符 str4 = f.readlines() print(str4) #三晾剖、關(guān)閉文件 f.close()
其他寫法:
#1.讀取文件的簡寫形式 #with open() as 變量 #好處:可以自動關(guān)閉文件,避免忘記關(guān)閉文件導致的資源浪費 path = "致橡樹.txt" with open(path,"r",encoding="gbk") as f: result = f.read() print(result) #2. try: f1 = open(path,"r",encoding="gbk") print(f1.read()) except FileNotFoundError as e: print("文件路徑錯誤",e) except LookupError as e: print("未知的編碼格式",e) except UnicodeDecodeError as e: print("讀取文件解碼錯誤",e) finally: if f1: f1.close()
讀取圖片等二進制文件:
#1. f = open("dog.jpg","rb") result = f.read() print(result) f.close() #2 with open("dog.jpg","rb") as f1: f1.read() #注意:讀取的是二進制文件梯嗽,讀取到的內(nèi)容為\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xdb\x0
2.2寫文件
操作步驟:
? a.打開文件:open()
? b.寫入數(shù)據(jù):write()
? c.刷新管道【內(nèi)部緩沖區(qū)】:flush()
? d.關(guān)閉文件:close()
代碼演示:
path = "file1.txt" #1.打開文件 #注意:寫入文件的時候齿尽,文件可以不存在,當open的時候會自動創(chuàng)建文件 #讀取文件的時候灯节,文件必須先存在循头,才能open f = open(path,"w",encoding="utf-8") #2.寫入數(shù)據(jù) #注意:將數(shù)據(jù)寫入文件的時候,默認是沒有換行的炎疆,如果向換行卡骂,則可以手動添加\n f.write("Python1805高薪就業(yè),走上人生巔峰") #3.刷新數(shù)據(jù)緩沖區(qū) #作用:加速數(shù)據(jù)的流動形入,保證緩沖區(qū)的流暢 f.flush() #4.關(guān)閉文件 f.close() #簡寫形式 with open(path,"w",encoding="utf-8") as f1: f1.write("hello") f.flush()
3.編碼和解碼
編碼:encode全跨,字符串類型轉(zhuǎn)換為字節(jié)類型
解碼:decode,字節(jié)類型轉(zhuǎn)換為字符串類型
注意:編碼和解碼的格式必須保持一致
代碼演示:
path = "file2.txt" #編碼:字符串----》字節(jié) with open(path,"wb") as f1: str = "today is a good day 今天是個好天氣" f1.write(str.encode("utf-8")) #解碼:字節(jié)----->字符串 with open(path,"rb") as f2: data = f2.read() print(data) print(type(data)) newData = data.decode("utf-8") print(newData) print(type(newData))
4.csv文件的讀寫
csv:逗號分隔值【Comma Separated Values】
一種文件格式亿遂,.csv,本質(zhì)是一個純文本文件浓若,可以作為不同程序之間數(shù)據(jù)交互的格式
打開方式:記事本,excel
4.1讀文件
代碼演示:
#C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\text.csv import csv #方式一:三部曲 def readCsv1(path): #1.打開文件 csvFile = open(path,"r") #2.將文件對象封裝成可迭代對象 reader= csv.reader(csvFile) #3.讀取文件內(nèi)容 #遍歷出來的結(jié)果為列表 for item in reader: print(item) #4.關(guān)閉文件 csvFile.close() readCsv1(r"C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\text.csv") #方式二:簡寫 def readCsv2(path): with open(path,"r") as f: reader = csv.reader(f) for item in reader: print(item) readCsv2(r"C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\text.csv")
4.2寫文件
代碼演示:
import csv #1.從列表寫入數(shù)據(jù) def writeCsv1(path): infoList = [['username', 'password', 'age', 'address'],['zhangsan', 'abc123', '17', 'china'],['lisi', 'aaabbb', '10', 'england']] #1.打開文件 #注意:如果不設(shè)置newline蛇数,每一行會自動有一個空行 csvFile = open(path,"w",newline="") #2.將文件對象封裝成一個可迭代對象 writer = csv.writer(csvFile) #3.寫入數(shù)據(jù) for i in range(len(infoList)): writer.writerow(infoList[i]) #4.關(guān)閉文件 csvFile.close() writeCsv1("file3.csv") #2.從字典寫入文件 def writeCsv2(path): dic = {"張三":123,"李四":456,"王麻子":789} csvFile = open(path, "w", newline="") writer = csv.writer(csvFile) for key in dic: writer.writerow([key,dic[key]]) csvFile.close() #3.簡寫形式 def writeCsv3(path): infoList = [['username', 'password', 'age', 'address'], ['zhangsan', 'abc123', '17', 'china'], ['lisi', 'aaabbb', '10', 'england']] with open(path, "w", newline="") as f: writer = csv.writer(f) for rowData in infoList: writer.writerow(rowData)