Python3 基础学习笔记 C09【文件和异常】
CSDN 課程推薦:《8小時Python零基礎(chǔ)輕松入門》,講師齊偉,蘇州研途教育科技有限公司CTO,蘇州大學應用統(tǒng)計專業(yè)碩士生指導委員會委員;已出版《跟老齊學Python:輕松入門》《跟老齊學Python:Django實戰(zhàn)》、《跟老齊學Python:數(shù)據(jù)分析》和《Python大學實用教程》暢銷圖書。
Python3 基礎(chǔ)學習筆記第九章【文件和異常】
目錄
- 【9.1】從文件中讀取數(shù)據(jù)
- 【9.1.1】讀取整個文件
- 【9.1.2】文件路徑
- 【9.1.3】逐行讀取
- 【9.1.4】創(chuàng)建一個包含文件各行內(nèi)容的列表
- 【9.1.5】使用文件的內(nèi)容
- 【9.2】寫入文件
- 【9.3】使用 try-except 代碼塊處理異常
- 【9.4】儲存數(shù)據(jù)
- 【9.4.1】使用 json.dump() 和 json.load()
- 【9.4.2】重構(gòu)
【9.1】從文件中讀取數(shù)據(jù)
【9.1.1】讀取整個文件
有一個文件,包含精確到小數(shù)點后30位的圓周率值,且在小數(shù)點后每10位處都換行:
Circumference rate.txt ----------------------- 3.141592653589793238462643383279以下兩個程序?qū)⒋蜷_并讀取這個文件,再將其內(nèi)容顯示到屏幕上:
#file_reader.pywith open('Circumference rate.txt') as file_object:contents = file_object.read()print(contents) #file_reader2.pycontents = open ('Circumference rate.txt') print(contents.read()) contents.close()函數(shù)open()接受一個參數(shù):要打開的文件的名稱,Python在當前執(zhí)行的文件所在的目錄中查找指定的文件;關(guān)鍵字with在不再需要訪問文件后將其關(guān)閉;也可以調(diào)用open()和close()來打開和關(guān)閉文件,如果使用這種方法,當程序存在bug時,close()語句未執(zhí)行,文件將不會被關(guān)閉;方法read()將讀取這個文件的全部內(nèi)容,并將其作為一個長長的字符串儲存在變量contents中,通過打印contents的值,就可以將這個文本文件的全部內(nèi)容打印出來:
3.141592653589793238462643383279輸出結(jié)果末尾有一空行,這是因為read()到達末尾時返回一個空字符串,而將這個空字符串顯示出來就是一個空行,如果要刪除末尾的空行,可在print語句中使用rstrip():
#file_reader.pywith open('Circumference rate.txt') as file_object:contents = file_object.read()print(contents.rstrip())輸出結(jié)果如下:
3.141592653589793238462643383279【9.1.2】文件路徑
相對文件路徑:假定程序文件位于python_work文件夾中,程序文件操作的文本文件位于python_work文件夾的子文件夾text_files中,此時可以使用相對文件路徑來打開該文本文件,相對文件路徑讓Python到指定的位置去查找,而該位置是相對于當前運行的程序所在目錄的
在Linux和OS X中,相對路徑類似于如下:
with open('text_files/filename.txt') as file_object:在Windows系統(tǒng)中,文件路徑中使用反斜杠(\)而不是斜杠(/):
with open('text_files\filename.txt') as file_object:絕對文件路徑:不用關(guān)心當前運行的程序儲存在什么地方,直接將文件在計算機中的準確位置告訴Python,這稱為絕對文件路徑,絕對路徑通常比相對路徑更長,因此將其儲存在一個變量中,再將變量傳遞給open()會有所幫助
在Linux和OS X中,絕對路徑類似于如下:
file_path = '/home/ehmatthes/other_files/text_files/filename.txt' with open(file_path) as file_object:在Windows系統(tǒng)中,絕對路徑類似于如下:
file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt' with open(file_path) as file_object:【9.1.3】逐行讀取
要以每次一行的方式檢查文件,可對文件對象使用for循環(huán):
#file_reader.pyfilename = 'Circumference rate.txt' with open(filename) as file_object:for line in file_object:print(line)在文件中每行的末尾都有一個看不見的換行符,而print語句也會加上一個換行符,因此每行末尾都有兩個換行符:一個來自文件,一個來自print語句,輸出結(jié)果如下:
3.141592653589793238462643383279要消除這些多余的空白行,可以使用rstrip():
#file_reader.pyfilename = 'Circumference rate.txt' with open(filename) as file_object:for line in file_object:print(line.rstrip())輸出結(jié)果如下:
3.141592653589793238462643383279【9.1.4】創(chuàng)建一個包含文件各行內(nèi)容的列表
使用關(guān)鍵字with時,open()返回的文件對象只在with代碼塊內(nèi)可用,如果要在with代碼塊外訪問文件的內(nèi)容,可在with代碼塊內(nèi)將文件的各行儲存在一個列表當中,并在with代碼塊外使用該列表:
#file_reader.pyfilename = 'Circumference rate.txt' with open(filename) as file_object:lines = file_object.readlines()for line in lines:print(line.rstrip())輸出結(jié)果與文件內(nèi)容完全一致
【9.1.5】使用文件的內(nèi)容
創(chuàng)建一個字符串,它包含文件中儲存的所有數(shù)字,且沒有任何空格:
#pi_string.pyfilename = 'Circumference rate.txt' with open(filename) as file_object:lines = file_object.readlines()pi_string = '' for line in lines:pi_string += line.rstrip()print(pi_string) print(len(pi_string))打印該字符串以及其長度:
3.1415926535 8979323846 2643383279 36由于原文件每行左邊都有空格,我們可以使用strip()而不是rstrip()來刪除它:
#pi_string.pyfilename = 'Circumference rate.txt' with open(filename) as file_object:lines = file_object.readlines()pi_string = '' for line in lines:pi_string += line.strip()print(pi_string) print(len(pi_string))輸出結(jié)果如下:
3.141592653589793238462643383279 32Python中有三個去除頭尾字符、空白符的函數(shù),它們依次為:
strip:用來去除頭尾字符、空白符(包括\n、\r、\t、’ ‘,即:換行、回車、制表符、空格)
lstrip:用來去除開頭字符、空白符(包括\n、\r、\t、’ ‘,即:換行、回車、制表符、空格)
rstrip:用來去除結(jié)尾字符、空白符(包括\n、\r、\t、’ ‘,即:換行、回車、制表符、空格)
注意:這些函數(shù)都只會刪除頭和尾的字符,中間的不會刪除。
用法分別為:
string.strip([chars])
string.lstrip([chars])
string.rstrip([chars])
參數(shù)chars是可選的,當chars為空,默認刪除string頭尾的空白符(包括\n、\r、\t、’ ')
當chars不為空時,函數(shù)會被chars解成一個個的字符,然后將這些字符去掉
它返回的是去除頭尾字符(或空白符)的string副本,string本身不會發(fā)生改變
【9.2】寫入文件
將一條簡單的消息儲存到文件中:
#write_message.pyfilename = 'programming.txt' with open(filename,'w') as file_object:file_object.write("I love programming!")調(diào)用open()時提供了兩個實參,第一個實參也是要打開文件的名稱,第二個實參(‘w’)告訴Python,我們要以寫入模式打開這個文件,打開文件時,可指定讀取模式(‘r’)、寫入模式(‘w’)、附加模式(‘a(chǎn)’)或者讓我們能夠讀取和寫入文件的模式(‘r+’),如果省略模式實參,則默認以只讀模式打開文件
附表:Python讀寫文件各種模式區(qū)別| r | 打開一個文件用于只讀 | 報錯 | - |
| rb | 以二進制格式打開一個文件用于只讀 | 報錯 | - |
| r+ | 打開一個文件用于讀和寫 | 報錯 | 否,追加寫 |
| rb+ | 以二進制格式打開一個文件用于讀和寫 | 報錯 | 否,追加寫 |
| w | 打開一個文件用于只寫 | 創(chuàng)建 | 是 |
| wb | 以二進制格式打開一個文件只用于只寫 | 創(chuàng)建 | 是 |
| w+ | 打開一個文件用于讀和寫 | 創(chuàng)建 | 是 |
| wb+ | 以二進制格式打開一個文件用于讀和寫 | 創(chuàng)建 | 是 |
| a | 打開一個文件用于追加 | 創(chuàng)建 | 否,追加寫 |
| ab | 以二進制格式打開一個文件用于追加 | 創(chuàng)建 | 否,追加寫 |
| a+ | 打開一個文件用于讀和寫 | 創(chuàng)建 | 否,追加寫 |
| ab+ | 以二進制格式打開一個文件用于追加 | 創(chuàng)建 | 否,追加寫 |
【9.3】使用 try-except 代碼塊處理異常
當我們嘗試將一個數(shù)字除以0時,會發(fā)生ZeroDivisionError異常:
>>> print(5/0) Traceback (most recent call last):File "<pyshell#0>", line 1, in <module>print(5/0) ZeroDivisionError: division by zero此時我們可以編寫一個try-except代碼塊來處理該異常:
try:print(5/0) except ZeroDivisionError:print("You can't divide by zero!")當我們運行該程序時,會出現(xiàn)提示:
You can't divide by zero!在try-except代碼塊中加入else,編寫一個只執(zhí)行除法運算的簡單計算器:
print("Give me two numbers,and I'll divide them.") print("Enter 'q' to quit.")while True:first_number = input("\nFirst number:")if first_number == 'q':breaksecond_number = input("\nSecond number:")if second_number == 'q':breaktry:answer = int(first_number)/int(second_number)except ZeroDivisionError:print("You can't divide by 0!")else:print(answer)運行程序:
Give me two numbers,and I'll divide them. Enter 'q' to quit.First number:45Second number:0 You can't divide by 0!First number:36Second number:8 4.5First number:q若不加入try-except代碼塊,我們在輸入0時,程序就會出現(xiàn)異常而崩潰,而try-except代碼塊很好的解決了這種問題,而且還起到了提示的作用,同樣的,try-except代碼塊也可以處理其他異常,如FileNotFoundError等
【9.4】儲存數(shù)據(jù)
【9.4.1】使用 json.dump() 和 json.load()
模塊json能夠?qū)⒑唵蔚腜ython數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)儲到文件中,并在程序再次運行時加載該文件中的數(shù)據(jù);編寫一個儲存一組數(shù)字的簡短程序,再編寫一個將這些數(shù)字讀取到內(nèi)存中的程序,第一個程序?qū)⑹褂?font color="#FF0000"> json.dump()來儲存這組數(shù)據(jù),而第二個程序?qū)⑹褂?font color="#FF0000"> json.load()。函數(shù) json.dump()接受兩個實參:要儲存的數(shù)據(jù)以及可用于儲存數(shù)據(jù)的文件對象:
#number_writer.pyimport jsonnumbers = [2,3,5,7,11,13]filename = 'numbers.json' with open(filename,'w') as f_obj:json.dump(numbers,f_obj)先導入模塊json,再創(chuàng)建一個數(shù)字列表, 通常用文件擴展名.json來指出文件儲存的數(shù)據(jù)為JSON格式,然后以寫入模式打開該文件,使用函數(shù)json.dump()將數(shù)字列表儲存到文件numbers.json中,打開該文件,數(shù)據(jù)的儲存格式與Python一樣:
[2, 3, 5, 7, 11, 13]再編寫一個程序,使用json.load()將這個列表讀取到內(nèi)存中:
#number_reader.pyimport jsonfilename = 'numbers.json' with open(filename) as f_obj:numbers = json.load(f_obj) print(numbers)輸出結(jié)果與number_writer.py中創(chuàng)建的數(shù)字列表相同:
[2, 3, 5, 7, 11, 13]進階:在同一個程序中使用 json.dump() 和 json.load():創(chuàng)建文件username.json儲存用戶名,從該文件中獲取用戶名,如果這個文件不存在,就在except代碼塊中提示用戶輸入用戶名,并將其儲存在username.json中:
#remember_me.pyimport json#如果以前儲存了用戶名,就加載它 #否則就提示用戶輸入用戶名并儲存它 filename = 'numbers.json' try:with open(filename) as f_obj:username = json.load(f_obj) except FileNotFoundError:username = input("What's your name?")with open(filename,'w') as f_obj:json.dump(username,f_obj)print("We'll remember you when you come back, " + username + "!") else: print("Welcome back, " + username + "!")以前沒有儲存用戶名,第一次運行程序:
What's your name?TRHX We'll remember you when you come back, TRHX!再次運行程序:
Welcome back, TRHX!【9.4.2】重構(gòu)
代碼能夠正確運行,但可以做進一步的改進——將代碼劃分為一系列完成具體工作的函數(shù),這樣的過程稱為重構(gòu),重構(gòu)讓代碼更清晰、更易于理解、更容易擴展
重構(gòu)remember_me.py,將大部分邏輯放到一個或者多個函數(shù)中:
重構(gòu)greet_user(),讓它不執(zhí)行這么多任務——將獲取儲存的用戶名的代碼移到另一個函數(shù)中:
#remember_me.pyimport jsondef get_stored_username():#如果儲存了用戶名,就獲取它filename = 'numbers.json'try:with open(filename) as f_obj:username = json.load(f_obj)except FileNotFoundError:return Noneelse:return usernamedef greet_user():#問候用戶,并指出其名字username = get_stored_username()if username:print("Welcome back, " + username + "!")else:username = input("What's your name?")filename = 'username.json'with open(filename,'w') as f_obj:json.dump(username,f_obj)print("We'll remember you when you come back, " + username + "!") greet_user()將greet_user()中的另一個代碼塊提取出來:將沒有儲存用戶名時提示用戶輸入的代碼放在一個獨立的函數(shù)中:
#remember_me.pyimport jsondef get_stored_username():#如果儲存了用戶名,就獲取它filename = 'numbers.json'try:with open(filename) as f_obj:username = json.load(f_obj)except FileNotFoundError:return Noneelse:return usernamedef get_new_username():#提示輸入用戶名username = input("What's your name?")filename = 'username.json'with open(filename,'w') as f_obj:json.dump(username,f_obj)return usernamedef greet_user():#問候用戶,并指出其名字username = get_stored_username()if username:print("Welcome back, " + username + "!")else:username = get_new_username()print("We'll remember you when you come back, " + username + "!") greet_user()最終版本實現(xiàn)了每個函數(shù)只負責單一而清晰的任務,我們在編寫程序時也要像這樣,要寫出清晰而易于維護和擴展的代碼
總結(jié)
以上是生活随笔為你收集整理的Python3 基础学习笔记 C09【文件和异常】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搭载骁龙8cx Gen 2:小米首款二合
- 下一篇: 【JS 逆向百例】有道翻译接口参数逆向