Python語言基礎的異常處理-檔案操作
阿新 • • 發佈:2021-10-07
異常
程式在執行過程當中,不可避免的會出現一些錯誤,比如:
使用了沒有賦值過的變數
使用了不存在的索引
除0
...
這些錯誤在程式中,我們稱其為異常。
程式執行過程中,一旦出現異常將會導致程式立即終止,異常以後的程式碼全部都不會執行!
處理異常
程式執行時出現異常,目的並不是讓我們的程式直接終止! Python是希望在出現異常時,我們可以編寫程式碼來對異常進行處理! try語句 try: 程式碼塊(可能出現錯誤的語句) except 異常型別 as 異常名: 程式碼塊(出現錯誤以後的處理方式) except 異常型別 as 異常名: 程式碼塊(出現錯誤以後的處理方式) except 異常型別 as 異常名: 程式碼塊(出現錯誤以後的處理方式) else: 程式碼塊(沒出錯時要執行的語句) finally: 程式碼塊(該程式碼塊總會執行) try是必須的 else語句有沒有都行 except和finally至少有一個 可以將可能出錯的程式碼放入到try語句,這樣如果程式碼沒有錯誤,則會正常執行, 如果出現錯誤,則會執行expect子句中的程式碼,這樣我們就可以通過程式碼來處理異常 避免因為一個異常導致整個程式的終止
# print('hello') # try: # # try中放置的是有可能出現錯誤的程式碼 # print(10/0) # except: # # except中放置的是出錯以後的處理防暑 # print('哈哈哈,出錯了~~~') # else: # print('程式正常執行沒有錯誤') # print('你好') # print(10/0) def fn(): print('Hello fn') print(a) print(10/0) def fn2(): print('Hello fn2') fn() def fn3(): print('Hello fn3') fn2() fn3()
異常物件
print('異常出現前') l = [] try: # print(c) # l[10] # 1 + 'hello' print(10/0) except NameError: # 如果except後不跟任何的內容,則此時它會捕獲到所有的異常 # 如果在except後跟著一個異常的型別,那麼此時它只會捕獲該型別的異常 print('出現 NameError 異常') except ZeroDivisionError: print('出現 ZeroDivisionError 異常') except IndexError: print('出現 IndexError 異常') # Exception 是所有異常類的父類,所以如果except後跟的是Exception,他也會捕獲到所有的異常 # 可以在異常類後邊跟著一個 as xx 此時xx就是異常物件 except Exception as e : print('未知異常',e,type(e)) finally : print('無論是否出現異常,該子句都會執行') print('異常出現後')
異常的傳播(丟擲異常)
當在函式中出現異常時,如果在函式中對異常進行了處理,則異常不會再繼續傳播,
如果函式中沒有對異常進行處理,則異常會繼續向函式呼叫處傳播,
如果函式呼叫處處理了異常,則不再傳播,如果沒有處理則繼續向呼叫處傳播
直到傳遞到全域性作用域(主模組)如果依然沒有處理,則程式終止,並且顯示異常資訊
當程式執行過程中出現異常以後,所有的異常資訊會被儲存一個專門的異常物件中,
而異常傳播時,實際上就是異常物件拋給了呼叫處
比如 : ZeroDivisionError類的物件專門用來表示除0的異常
NameError類的物件專門用來處理變數錯誤的異常
....
在Python為我們提供了多個異常物件
丟擲異常
- 可以使用 raise 語句來丟擲異常,
raise語句後需要跟一個異常類 或 異常的例項
# 也可以自定義異常類,只需要建立一個類繼承Exception即可
class MyError(Exception):
pass
def add(a,b):
# 如果a和b中有負數,就向呼叫處丟擲異常
if a < 0 or b < 0:
# raise用於向外部丟擲異常,後邊可以跟一個異常類,或異常類的例項
# raise Exception
# 丟擲異常的目的,告訴呼叫者這裡呼叫時出現問題,希望你自己處理一下
# raise Exception('兩個引數中不能有負數!')
raise MyError('自定義的異常')
# 也可以通過if else來代替異常的處理
# return None
r = a + b
return r
print(add(-123,456))
檔案(File)
- 通過Python程式來對計算機中的各種檔案進行增刪改查的操作
- I/O(Input / Output)
- 操作檔案的步驟:
① 開啟檔案
② 對檔案進行各種操作(讀、寫),然後儲存
③ 關閉檔案
開啟檔案
# open(file, mode='r', buffering=-1, encoding_=None, errors=None, newline=None, closefd=True, opener=None)
# 使用open函式來開啟一個檔案
# 引數:
# file 要開啟的檔案的名字(路徑)
# 返回值:
# 返回一個物件,這個物件就代表了當前開啟的檔案
# 建立一個變數,來儲存檔案的名字
# 如果目標檔案和當前檔案在同一級目錄下,則直接使用檔名即可
file_name = 'demo.txt'
# 在windows系統使用路徑時,可以使用/來代替 \
# 或者可以使用 \\ 來代替 \
file_name = 'hello\\demo.txt'
file_name = r'hello\demo.txt' #或者也可以使用原始字串(在前面加r)
# 表示路徑,可以使用..來返回一級目錄
file_name = '../hello/demo.txt'
# 如果目標檔案距離當前檔案比較遠,此時可以使用絕對路徑
# 絕對路徑應該從磁碟的根目錄開始書寫
file_name = r'C:\Users\lilichao\Desktop\hello.txt'
# file_obj = open(file_name) # 開啟 file_name 對應的檔案
# print(file_obj)
關閉檔案
# 開啟檔案
file_name = 'demo.txt'
# 呼叫open()來開啟檔案
# file_obj = open(file_name)
# # 當我們獲取了檔案物件以後,所有的對檔案的操作都應該通過物件來進行
# # 讀取檔案中的內容
# # read()方法,用來讀取檔案中的內容,它會將內容全部儲存為一個字串返回
# content = file_obj.read()
# print(content)
# # 關閉檔案
# # 呼叫close()方法來關閉檔案
# file_obj.close()
# with ... as 語句
# with open(file_name) as file_obj :
# # 在with語句中可以直接使用file_obj來做檔案操作
# # 此時這個檔案只能在with中使用,一旦with結束則檔案會自動close()
# print(file_obj.read())
file_name = 'hello'
try:
with open(file_name) as file_obj :
print(file_obj.read())
except FileNotFoundError:
print(f'{file_name} 檔案不存在~~')
檔案的讀取_1
file_name = 'demo2.txt'
try:
# 呼叫open()來開啟一個檔案,可以將檔案分成兩種型別
# 一種,是純文字檔案(使用utf-8等編碼編寫的文字檔案)
# 一種,是二進位制檔案(圖片、mp3、ppt等這些檔案)
# open()開啟檔案時,預設是以文字檔案的形式開啟的,但是open()預設的編碼為None
# 所以處理文字檔案時,必須要指定檔案的編碼
with open(file_name,encoding='utf-8') as file_obj:
# 通過 read() 來讀取檔案中的內容
# 如果直接呼叫read()它會將文字檔案的所有內容全部都讀取出來
# 如果要讀取的檔案較大的話,會一次性將檔案的內容載入到記憶體中,容易導致記憶體洩漏
# 所以對於較大的檔案,不要直接呼叫read()
# help(file_obj.read)
# read()可以接收一個size作為引數,該引數用來指定要讀取的字元的數量
# 預設值為-1,它會讀取檔案中的所有字元
# 可以為size指定一個值,這樣read()會讀取指定數量的字元,
# 每一次讀取都是從上次讀取到位置開始讀取的
# 如果字元的數量小於size,則會讀取剩餘所有的
# 如果已經讀取到了檔案的最後了,則會返回''空串
# content = file_obj.read(-1)
content = file_obj.read(6)#鋤禾日當午
content = file_obj.read(6)#汗滴禾下土
content = file_obj.read(6)#誰知盤中餐
content = file_obj.read(6)#粒粒皆辛苦
# print(content)
# print(len(content))
except FileNotFoundError :
print(f'{file_name} 這個檔案不存在!')
# 讀取大檔案的方式
file_name = 'demo.txt'
try:
with open(file_name,encoding='utf-8') as file_obj:
# 定義一個變數,來儲存檔案的內容
file_content = ''
# 定義一個變數,來指定每次讀取的大小
chunk = 100
# 建立一個迴圈來讀取檔案內容
while True:
# 讀取chunk大小的內容
content = file_obj.read(chunk)
# 檢查是否讀取到了內容
if not content:
# 內容讀取完畢,退出迴圈
break
# 輸出內容
# print(content,end='')
file_content += content
except FileNotFoundError :
print(f'{file_name} 這個檔案不存在!')
print(file_content)
檔案的讀取_2
import pprint
import os
file_name = 'demo.txt'
with open(file_name , encoding='utf-8') as file_obj:
# readline()
# 該方法可以用來讀取一行內容
# print(file_obj.readline(),end='')
# print(file_obj.readline(),end='')
# print(file_obj.readline(),end='')
# readlines()
# 該方法用於一行一行的讀取內容,它會一次性將讀取到的內容封裝到一個列表中返回
# r = file_obj.readlines()
# pprint.pprint(r[0])
# pprint.pprint(r[1])
# pprint.pprint(r[2])
for t in file_obj:
print(t)
檔案的寫入
file_name = 'demo5.txt'
# 使用open()開啟檔案時必須要指定開啟檔案所要做的操作(讀、寫、追加)
# 如果不指定操作型別,則預設是 讀取檔案 , 而讀取檔案時是不能向檔案中寫入的
# r 表示只讀的
# w 表示是可寫的,使用w來寫入檔案時,如果檔案不存在會建立檔案,如果檔案存在則會截斷檔案
# 截斷檔案指刪除原來檔案中的所有內容
# a 表示追加內容,如果檔案不存在會建立檔案,如果檔案存在則會向檔案中追加內容
# x 用來新建檔案,如果檔案不存在則建立,存在則報錯
# + 為操作符增加功能
# r+ 即可讀又可寫,檔案不存在會報錯
# w+ 即可讀又可寫,檔案不存在則會建立檔案
# a+ 同w+
# with open(file_name , 'w' , encoding='utf-8') as file_obj:
# with open(file_name , 'r+' , encoding='utf-8') as file_obj:
with open(file_name , 'x' , encoding='utf-8') as file_obj:
# write()來向檔案中寫入內容,
# 如果操作的是一個文字檔案的話,則write()需要傳遞一個字串作為引數
# 該方法會可以分多次向檔案中寫入內容
# 寫入完成以後,該方法會返回寫入的字元的個數
file_obj.write('aaa\n')
file_obj.write('bbb\n')
file_obj.write('ccc\n')
r = file_obj.write(str(123)+'123123\n')
r = file_obj.write('今天天氣真不錯')
print(r)
對二進位制檔案的操作
file_name = 'c:/Users/lilichao/Desktop/告白氣球.flac'
# 讀取模式
# t 讀取文字檔案(預設值)
# b 讀取二進位制檔案
with open(file_name , 'rb') as file_obj:
# 讀取文字檔案時,size是以字元為單位的
# 讀取二進位制檔案時,size是以位元組為單位
# print(file_obj.read(100))
# 將讀取到的內容寫出來
# 定義一個新的檔案
new_name = 'aa.flac'
with open(new_name , 'wb') as new_obj:
# 定義每次讀取的大小
chunk = 1024 * 100
while True :
# 從已有的物件中讀取資料
content = file_obj.read(chunk)
# 內容讀取完畢,終止迴圈
if not content :
break
# 將讀取到的資料寫入到新物件中
new_obj.write(content)
讀取檔案時的位置
# with open('demo.txt','rb') as file_obj:
# # print(file_obj.read(100))
# # print(file_obj.read(30))
# # seek() 可以修改當前讀取的位置
# file_obj.seek(55)
# file_obj.seek(80,0)
# file_obj.seek(70,1)
# file_obj.seek(-10,2)
# # seek()需要兩個引數
# # 第一個 是要切換到的位置
# # 第二個 計算位置方式
# # 可選值:
# # 0 從頭計算,預設值
# # 1 從當前位置計算
# # 2 從最後位置開始計算
# print(file_obj.read())
# # tell() 方法用來檢視當前讀取的位置
# print('當前讀取到了 -->',file_obj.tell())
with open('demo2.txt','rt' , encoding='utf-8') as file_obj:
# print(file_obj.read(100))
# print(file_obj.read(30))
# seek() 可以修改當前讀取的位置
file_obj.seek(9)
# seek()需要兩個引數
# 第一個 是要切換到的位置
# 第二個 計算位置方式
# 可選值:
# 0 從頭計算,預設值
# 1 從當前位置計算
# 2 從最後位置開始計算
print(file_obj.read())
# tell() 方法用來檢視當前讀取的位置
print('當前讀取到了 -->',file_obj.tell())
檔案的其他操作
import os
from pprint import pprint
# os.listdir() 獲取指定目錄的目錄結構
# 需要一個路徑作為引數,會獲取到該路徑下的目錄結構,預設路徑為 . 當前目錄
# 該方法會返回一個列表,目錄中的每一個檔案(夾)的名字都是列表中的一個元素
r = os.listdir()
# os.getcwd() 獲取當前所在的目錄
r = os.getcwd()
# os.chdir() 切換當前所在的目錄 作用相當於 cd
# os.chdir('c:/')
# r = os.getcwd()
# 建立目錄
# os.mkdir("aaa") # 在當前目錄下建立一個名字為 aaa 的目錄
# 刪除目錄
# os.rmdir('abc')
# open('aa.txt','w')
# 刪除檔案
# os.remove('aa.txt')
# os.rename('舊名字','新名字') 可以對一個檔案進行重新命名,也可以用來移動一個檔案
# os.rename('aa.txt','bb.txt')
os.rename('bb.txt','c:/users/lilichao/desktop/bb.txt')
pprint(r)