摘要:本章主要是學習的文件操作,主要是從文件中讀取數據以及將數據存儲到文件中,還有錯誤處理,異常類,模塊等。函數返回一個文件對象,用于接收該對象。異常中使用被稱為異常的特殊對象來管理程序執行期間發生的錯誤。
《Python編程:從入門到實踐》筆記。1. 從文件中讀數據 1.1 讀取整個文件
本章主要是學習Python的文件操作,主要是從文件中讀取數據以及將數據存儲到文件中,還有錯誤處理,異常類,json模塊等。
以下文件pi_digits.txt包含了精確到小數點后30位的圓周率數據
# pi_digits.txt文件 3.1415926535 8979323846 2643383279 # 代碼: with open("pi_digits.txt", "r") as file_object: contents = file_object.read() # 一次性讀取整個文件 print(contents) # 結果:和上述文件內容一樣
從上述代碼可以看出,我們打開文件使用open()函數,該函數至少接收一個參數,即文件路徑。讀取文件時需要向open()函數指明是用什么方式讀取文件,是只讀("r"),只寫("w"),末尾添加("a")還是讀寫均可("r+"),open()函數默認以“只讀”方式讀取文件。這只是4中常用的文件讀取方式,此外還有至少8種讀寫方式。open()函數返回一個文件對象,file_object用于接收該對象。通過文件對象的read()方法讀取文件內容,且該方法返回整個文件的內容。
上述代碼中的文件和源代碼在同一目錄中。注意文件路徑的問題,絕對路徑(不提倡)和相對路徑(相對于源文件的路徑)以及Windows和Linux下路徑的寫法。
注意代碼中的with關鍵字。其實讀寫文件不需要該關鍵字,打開文件使用open()函數,文件讀取完后關閉文件使用close()函數,讀取內容可以調用read()方法。而之所以使用with關鍵字,主要是因為①你最后忘記關閉文件,就想忘了關燈一樣;②也可能是在關閉前程序出錯,導致close()語句未執行。這些讓文件沒有關閉的情況都有可能導致數據丟失或損壞。with關鍵字則被用來應對這些情況,它保證在結束with塊時,文件一定會被關閉。
1.2 逐行讀取上述代碼一次性讀取整個文件,這在文件較小或者內存充裕的時候沒有問題,但如果文件特別大,內存容量又很羞澀,則只能逐行讀取:
# 代碼: file_name = "pi_digits.txt" with open(file_name) as file_pi: for line in file_pi: # 也可以通過while循環配合readline()方法逐行讀取文件 print(line) # 結果: 3.1415926535 8979323846 2643383279
這里需要注意一個問題,就是對行以及文件末尾空字符的讀取問題,read()和readline()方法會讀取末尾的空字符(這里是換行符)。我們可以通過之前講的rstrip()方法去掉末尾的空字符。
1.3 將文件每一行放入列表中readlines()方法將文件中每一行存入列表并返回,以下代碼進一步處理文件中的內容:
# 代碼: file_name = "pi_digits.txt" with open(file_name) as file_pi: lines = file_pi.readlines() pi_string = "" for line in lines: pi_string += line.strip() print(pi_string) print(len(pi_string)) # 結果: 3.141592653589793238462643383279 32
注意,Python從文件中讀取出的所有內容都是字符串,如果你想要的是數字,請記得轉換。
2. 寫入文件以下是一個簡單的文件寫入程序:
filename = "python.txt" with open(filename, "w") as file_obj: file_obj.write("I love python!")
執行改代碼后你會看到在同一目錄下會生成一個名為“python.txt"的文件。需要注意的是,以"w"方式打開文件,如果要寫入的文件不存在,則會自動創建該文件;如果該文件存在,該文件的內容會被清空,然后再寫入。如果不想文件被清空,請使用"a"(文件指針放在文件末尾)或"r+"(文件指針指向文件開頭)方式打開文件。還有一點,write()函數不會在文件末尾添加換行符,如果需要換行符,請自行添加。
3. 異常Python中使用被稱為異常的特殊對象來管理程序執行期間發生的錯誤。每當代碼運行時如果遇到了不能處理的錯誤,Python都會創建一個異常對象,如果程序中沒有處理該對象的相關代碼,程序將會停止,并顯示一個traceback,其中包含異常的相關報告。如果不想程序因為某些異常而終止運行,則需要我們使用try-except代碼塊自行處理異常。以下是一個處理除零錯誤ZeroDivisionError的例子:
# 代碼: # 捕捉異常 try: resule = 5 / 0 except ZeroDivisionError: print("You can"t divide by zero! ") # 不捕捉異常 print(5 / 0) # 結果: You can"t divide by zero! Traceback (most recent call last): File "division.py", line 29, inprint(5 / 0) ZeroDivisionError: division by zero
如果你打算編寫一個計算器應用,那么這段代碼必不可少。第一個例子表明,即使發生了異常,只要異常被我們捕捉,那么程序便不會終止。如果只想捕捉異常,但暫時又不想處理,可以將上述的print("You can"t divide by zero! ")替換為pass語句。如果想捕獲所有的異常,則except后面不指定異常類型。
3.1 else代碼塊try-except代碼塊還可以和else語句組合形成try-except-else代碼塊,該結構表示,如果捕獲了異常,這執行except中的程序,沒有發生異常則執行else中的程序。以下程序是一個循環統計文件中單詞數的例子,文件讀取的部分被放到了函數中,該函數檢測有沒有發生FileNotFoundError:
# 代碼: def count_words(filename): """計算一個文件大致包含多少個單詞""" try: with open(filename) as f_obj: contents = f_obj.read() except FileNotFoundError: msg = "Sorry, the file" + filename + " does not exist." print(msg) else: # 計算文件大只包含多少個單詞 words = contents.split() num_words = len(words) print("The file " + filename + " has about " + str(num_words) + "words.") filenames = ["alice.txt", "siddhartha.txt", "moby_dick.txt", "little_women.txt"] for filename in filenames: count_words(filename) # 結果: The file alice.txt has about 29461 words. Sorry, the file siddhartha.txt does not exist. The file moby_dick.txt has about 215136 words. The file little_women.txt has about 189097 words.
對else的補充:其實else不光可以和if,try-except結合,還可以和for循環和while循環結合,比如:
for i in range(10): pass else: pass i = 0 while i < 10: i++ else: pass
這里的else表示當循環結束后執行一些語句,比如提示之類的。
3.2 決定報告哪些錯誤編寫得很好且經過詳盡測試的代碼不容易出現內部錯誤,如語法或邏輯錯誤,但只要程序依賴于外部因素,如用戶輸入、存在指定的文件、有網絡連接等,就有可能出現異常。憑經驗可判斷改在程序的什么地方包含異常處理塊,以及出現錯誤時該向用戶提供多少相關的信息。
4. 存儲數據很多程序要求用戶輸入某種信息,也有可能程序中某些變量的數據在程序結束后不能丟失(比如機器學習最后訓練出來的模型參數),這是就需要將這些信息以文件的形式存下來。存儲數據的方式有很多,現在比較簡單且通用的是使用json來存儲信息。json(JavaScript Object Notation)格式最初是為JavaScript 開發的,但隨后成了一種常見格式,并被包括Python在內的眾多語言采用。以下是一個經過了重構的存儲用戶信息的例子:
import json def get_stored_username(filename): """如果存儲了用戶名,就獲取它""" try: with open(filename) as f_obj: username = json.load(f_obj) except FileNotFoundError: return None else: return username def get_new_username(filename): """提示用戶輸入用戶名,并存入文件""" username = input("What"s your name?") with open(filename, "w") as f_obj: json.dump(username, f_obj) return username def greet_user(filename): """向用戶打招呼""" username = get_stored_username(filename) if username: print("Welcome back, " + username + "!") else: username = get_new_username(filename) print("We"ll remember you when you come back, " + username + "!") filename = "username.json" greet_user(filename)
代碼就不運行了,請各位自行推導程序的結果。最后在username.json文件中會存有用戶的信息。但要注意一點,json根據數據類型來存儲數據,雖然最后都是字符串,但這個過程不需要我們干預,比如要存一個列表,并不需要我們先將其轉換為字符串,再存入json,讀取數據時也不需要我們先讀取為字符串,再轉換成列表,我們只需直接存取即可,轉換工作由json模塊自動完成。
迎大家關注我的微信公眾號"代碼港" & 個人網站 www.vpointer.net ~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41792.html
摘要:第行把具名元組以的形式返回。對序列使用和通常號兩側的序列由相同類型的數據所構成當然不同類型的也可以相加,返回一個新序列。從上面的結果可以看出,它雖拋出了異常,但仍完成了操作查看字節碼并不難,而且它對我們了解代碼背后的運行機制很有幫助。 《流暢的Python》筆記。接下來的三篇都是關于Python的數據結構,本篇主要是Python中的各序列類型 1. 內置序列類型概覽 Python標準庫...
摘要:前言本文記錄自己在學習當中遇到的各種大小問題,持續更新。錯誤分析本身是一個網絡引擎框架,的運行依賴于。在打開新建的項目后,報錯顯示。錯誤分析的默認依賴項當中沒有,或者說默認查找的路徑中找不到。 前言 本文記錄自己在學習scrapy當中遇到的各種大小問題,持續更新。 環境簡介: 語言版本 爬蟲框架 IDE 系統 python3.5 scrapy1.4.0 pycharm win1...
摘要:具體方法和上一篇一樣,也是用各個分量的哈希值進行異或運算,由于的分量可能很多,這里我們使用函數來歸約異或值。每個分量被映射成了它們的哈希值,這些哈希值再歸約成一個值這里的傳入了第三個參數,并且建議最好傳入第三個參數。 《流暢的Python》筆記。本篇是面向對象慣用方法的第三篇。本篇將以上一篇中的Vector2d為基礎,定義多維向量Vector。 1. 前言 自定義Vector類的行為...
摘要:本篇內容將從鴨子類型的動態協議,逐漸過渡到使接口更明確能驗證實現是否符合規定的抽象基類。抽象基類介紹完動態實現接口后,現在開始討論抽象基類,它屬于靜態顯示地實現接口。標準庫中的抽象基類從開始,標準庫提供了抽象基類。 《流暢的Python》筆記。本篇是面向對象慣用方法的第四篇,主要討論接口。本篇內容將從鴨子類型的動態協議,逐漸過渡到使接口更明確、能驗證實現是否符合規定的抽象基類(Abst...
摘要:本節中將繪制幅圖像收盤折線圖,收盤價對數變換,收盤價月日均值,收盤價周日均值,收盤價星期均值。對數變換是常用的處理方法之一。 《Python編程:從入門到實踐》筆記。本篇是Python數據處理的第二篇,本篇將使用網上下載的數據,對這些數據進行可視化。 1. 前言 本篇將訪問并可視化以兩種常見格式存儲的數據:CSV和JSON: 使用Python的csv模塊來處理以CSV(逗號分隔的值)...
閱讀 3300·2021-09-30 09:54
閱讀 3782·2021-09-22 15:01
閱讀 3105·2021-08-27 16:19
閱讀 2572·2019-08-29 18:39
閱讀 2146·2019-08-29 14:09
閱讀 623·2019-08-26 10:23
閱讀 1337·2019-08-23 12:01
閱讀 1862·2019-08-22 13:57