一、錯誤和異常
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í)行對應(yīng)的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)