好久不見,太久沒更新了,最近事情有點多。
這章主要會講文件介紹,將數據寫入文件,從文件中讀取數據以及處理異常。
文件輸入輸出簡介
要使程序在運行期間保留數據,必須保存數據。
----數據保存到文件中,通常保存在計算機磁盤上。
----保存的數據可以在以後檢索和使用。
文件對於在打開和關閉應用程序之間保存數據非常有用。
輸出文件是數據寫入的文件;
輸入文件:從中讀取數據的文件。
程序使用文件時的三個步驟:
–—打開文件
–—處理文件(讀/寫)
–—關閉文件
將數據寫入文件並讀取
當我們將數據寫入文件時就會發生這種情況:
有一個pay_rate變量和employee_id變量和employee_name變量。數據從內存RAM中複製出來(RAM是一種快速隨機存取存儲器,在我們不把文件保存到某個地方之前一直在使用它並被保存在磁盤),磁盤的特定位置供日後使用或諮詢。
當我們從文件中讀取數據時,我們使用Python腳本在我們的磁盤裏,我們搜索數據,數據從文件複製到內存中,這裏是更容易更快訪問的地方。可以被變量使用,所以我們可以把之前存儲在磁盤上的數據存儲回變量中。所以pay_rate會有18.65這個值…(RAM就像是中介)
文件類型和文件訪問方法
不同類型的文件有不同文件的訪問方法。
一般來說,當我們用Python處理文件時,有兩種類型的文件:
----文本文件:包含已編碼爲文本的數據。(文本文件可以在Mac上用文本編輯創建,在Windows上用記事本創建,在Linux上用nano創建)
----二進制文件:包含尚未轉換爲文本的數據。可包含任何類型的數據和代碼以及計算機存儲和處理的二進制文件。
訪問文件中存儲的數據的兩種方法:
----順序訪問:文件從頭到尾順序讀取,不能向前跳。(所以我們讀的是一個完整的文件,沒有跳過的機會)
----直接訪問可以直接跳轉到文件中的任何數據。(因此不必一步一步地讀取整個文件,更自由, 更直接。)
文件名和文件對象
文件顯然有文件名還有一個對象的概念。
文件擴展名:在文件名末尾出現句點的短字符序列。
擴展名指示文件中存儲的數據類型。(每個文件都有一個擴展名,文本文件可以有txt,Doc文件可以有doc,電影可以有mov或mp4等…這就可以告訴我們的電腦存儲了什麼類型的文件。)
文件對象是在Python中與特定文件相關聯的對象。
這個概念爲程序提供了一種方法來處理變量引用的文件對象。(如下圖所示:)
有一個variabke_name變量過去連接一個文件對象,該對象引用到磁盤上的特定文件。所以我們的文件對象使我們的程序去處理文件,是個中介,它被變量引用了,然後進去設法與磁盤中的文件和數據通信。
在Python中打開文件
用python打開一個文件非常簡單,會有一個函數,這個函數叫做open。
open函數:用於打開文件:
–—創建一個文件對象並將其與磁盤上的文件關聯
–—一般格式:file_variable = open(filename, mode)
mode:是一個指定文件打開方式的字符串。
我們可以用不同的方式打開文件:r,w,a。
只讀('r')沒有機會編輯和修改文件上的數據 、 寫入('w')可以把數據寫在文件上 , 附加('a')可以在文件中附加數據而不必編輯已存在的內容。
例如我們可以有一個customer_file,它是一個保存文件對象的變量。customer_file = open(“customer.txt”, “r”)就是把一個字符串指向一個名爲customer.txt的文件,它存儲在我們的筆記本中,然後會把mode‘r’傳遞給它,這是在讀文件,把數據存儲在對象中。
如果open函數接收到不包含路徑的文件名,則假定那個文件和程序在同一目錄下。
(如果我們要打開的文件和腳本在同一個地方,我們可以給它起個名字。如果文件存儲在電腦的其他地方,我們得說清楚文件在哪兒。)
可以在“open函數”參數中指定替代路徑和文件名。在路徑字符串文本前面加上字母r
(如果文件存儲在其他地方,我們可以指定文件的確切位置,並在路徑字符串文字前加上字母r作爲前綴。例如:test_file = open(r’C:\Users\Blake\temp\test.txt’, ‘w’)
寫入文件
文件對象正確的方法是用於將數據寫入文件中:用到write方法。格式:file_variable.write(string)
應使用文件對象close方法關閉文件,格式:file_variable.close()
舉例:
創建一個新文件函數,首先要做的第一件事情就是打開此文件Frist_Python_File.txt,write模式。
調用file.write,“\n”表示看不見的新字符
(每次放的時候就開始寫新的一行代碼)
調用…
調用…
當我們寫完時,可以用.close關閉文件
然後打印一個File created,讓我們的用戶知道我們已經完成了對文件的寫入。
最後調用create_new_file(),這將在我保存腳本的同一文件夾中創建一個名爲First Python_file.txt的新文件,文件將包含First line,Second line和Third line,這三行在不同的行上面,因爲在每個字符串的末尾都加了“\n”。
從文件讀取數據
從文件中讀取數據非常與寫相似。
read方法:將整個文件內容讀入內存的文件對象方法:
–—僅當文件已打開進行讀取時纔有效
–—作爲字符串返回的內容,
格式:content = file_variable.read()
readline方法:從文件中讀取行的文件對象方法:
(不是讀整個文件) 該行作爲字符串返回,包括 ‘\n’(選擇讀取的行作爲字符串返回)格式:line = file_variable.readline()
舉例:
一個叫做read_data的函數,我們要做的是從上面讀取數據,要讀的是First_Python_File.txt(之前前面所建立的文件),
三次調用read_line,我們都會轉到文件的下一行,因此這三個方法調用將存儲在這三個變量中之前文件的三行。
當完成閱讀時,調用close方法並將三個內容打印給控制檯。
運行代碼(最後一行應改爲read_data() )
使用循環處理文件
文件通常用來保存大量數據,通常文件中存儲的項目數是未知的。
循環通常涉及從文件中讀寫,循環可以幫助我們遍歷文件並讀取所有內容。
流程圖過程:
1:打開文件
2:用readline從文件中讀取第一行
3:詢問readline是否返回了一個空字符串。如果字符串不是空的就意味着文件還有內容要傳遞。我們要繼續存儲文件中的內容。再用readline讀第二行,一遍一遍地重複直到python腳本發現沒有文本爲止。
4:關閉文件
當到達文件末尾時,readline方法會使用一個空字符串作爲前哨。
空字符串意味着文件完成了,所以我們可以用它來檢查文件是否真的完成了。在文件到達末尾時,要退出循環:while line != ''
舉例子:
file = open(“MyFile.txt", "r") '將MyFile.txt作爲讀取文件打開並將其存儲在file變量裏'
line = file.readline() "創建一個line變量並讀取文本的第一行 "
while line !='': "如果line變量不同於空字符串,就會打印出來並繼續,會一直持續下去直到找到空行爲止"
print(line)
line = file.readline()
file.close()
將數據追加到現有文件
用“w”模式打開一個文件時,如果該文件已存在,則會被覆蓋。
如果使用w文件不存在,python會創建一個文件。但是如果使用w並且文件已經存在了,python會刪除這個文件並創建一個全新的。所以如果我們不想刪除存在的文件的內容。而是想把東西加進去,我們需要用到a。
要將數據附加到文件,使用“a”模式:
----如果文件存在,則不刪除它,如果文件不存在,則創建它。
–----在當前內容的末尾將數據寫入文件
寫入和讀取數字數據:
---數字必須先轉換爲字符串,然後才能寫入文件。
str函數可以將任何數值轉換爲字符串。
----數字可以作爲字符串從文本文件中讀取。必須轉換爲數值類型才能執行數學運算。使用int和float函數將字符串轉換爲數值。
分割函數
也有一些可以在文件中使用的新函數—split函數。
**Readline函數返回一個字符串。在某些情況下,您可能需要將一個大字符串分解爲較小的塊或字符串。**當我們有個很長的代碼行並需要分開時,可以用到split函數。
x = "blue,red,green"
colours = x.split(",") "在x上調用了split方法,把,逗號作爲參數給它"
print(colours)
當我們打印出來:
split方法需要一個很長的字符串並提供一個分隔符,在這種情況下這個逗號創造了迭代,就變成了列表。在這種情況下,取字符串的每個元素,直到找到逗號爲止。當找到逗號時,將其存儲在與列表相反的位置,然後爲下一個創建一個新的元素。
當我們有一個更長的字符串時:
words = "This is random text we’re going to split apart"
words2 = words.split(" ")"調用split傳遞給它一個空白。"
print(words2)
當打印出來時:
會有一個完整的單字列表。
也可以使用split拆分對象:
class Employee:
def __init__(self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
def get_employee_info(self):
print( "Employee name is: %s" %self.name)
print("Employee age is: %d" %self.age)
print("Employee salary: is %f" %self.salary)
#爲類實例化
employee_1 = "Julian, 45, 35000.00" #將字符串放入變量裏
employee_2 = "Sarah Smith, 22, 26000.00" #這基本上會像對字符串的作用一樣作用於對象。這可以來自函數file.readline()
emp1_lst = employee_1.split(",")
emp2_lst = employee_2.split(",")#這裏拿走了employee的對象,應用split在emp1_1st裏存儲起來。這樣就可以從文件或輸入函數中的任意位置獲取此字符串。
emp1_obj = Employee(emp1_lst[0], int(emp1_lst[1]), float(emp1_lst[2]))
emp2_obj = Employee(emp2_lst[0], int(emp2_lst[1]), float(emp2_lst[2]))#通過剛剛使用split創建的間隔,可以從employee類中創建一個對象。將在上面零位置創建的列表作爲name傳遞。依次傳遞參數。
emp1_obj.get_employee_info()
print() # new line
emp2_obj.get_employee_info()
這個代碼輸出是:
split對於接收復雜的字符串並將其傳遞給對象關聯創建單個元素非常有用。