Python學習(22)--檔案操作1
之前我們介紹到的資料類型,如清單,字典或者一個數字,字元等等。都是在程式運作時存儲在記憶體中的,存儲在記憶體中的資料不穩定,程式運作完後很難再找回。但是某些資料我們需要穩定的存儲,如一個班級的成績,這種随時可能被查閱的資料,最好就是存儲在硬碟上的檔案或者資料庫中。這一節,我們就來介紹Python中對檔案的操作。
(1)檔案操作的基本流程
Python中對檔案操作的流程基本為3個步驟:打開檔案,檔案操作,關閉檔案。在Python中打開檔案使用的内置函數為open(filename,flag),filename為檔案的名字,flag指定對檔案操作的權限,不指定flag的值預設為隻讀操作,該函數傳回的是一個檔案對象fileObject,我們可以對這個檔案對象進行相應的操作;關閉檔案就是調用fileObject的close()方法,關閉檔案對象後就不能再對檔案進行任何操作。如下:
<b>[python]</b> view plain copy
fo=open("message.txt")#打開檔案
print(fo.read())#讀取資料
fo.close()#關閉檔案
print(fo.read())#關閉檔案後讀取資料
程式為打開一個檔案,并讀取檔案中的資料。最後關閉檔案,代碼列印結果如下:

如上讀取出message.txt中的檔案内容為"hello world!",當我們關閉檔案後再次讀取檔案内容,報錯為"I/O operation on closed file",這是因為在檔案關閉後對檔案的操作權限也沒有了。
(2)對檔案的讀寫操作
之前我們介紹過,預設情況下内置函數open(filename,flag)對檔案的操作權限為隻讀,當我們需要對檔案進行寫操作時,還需要擷取相應的寫權限。flag就是我們擷取權限的參數,對檔案對象fileObject進行寫操作,使用的方法為write(string),即将資料string寫入檔案。如下:
fo=open("test.txt","w+")
fo.write("hello world")
fo.close()
fo=open("test.txt")
print(fo.read())
列印結果如下:
如上,我們打開檔案test.txt,并對其進行讀寫操作(flag="w+",表示對檔案讀寫的權限),接着把"hello world"寫入檔案,再次打開檔案并讀取,列印出的檔案内容"hello world"。
更多有關檔案操作的權限如下圖:
如上,‘a’表示檔案末尾寫入内容的權限,r+可以對檔案進行讀寫操作等等。
(3)檔案指針
在Python中讀取檔案時,是靠指針來讀取的,當讀取一個機關的資料,指針就下移一個機關,再讀取下一個機關的資料。下面我們來比較以下兩個程式的不同,來解釋Python檔案指針的機制。如下:
fo=open("test.txt","r+")
fo.write("nihao world")
在程式中,首先,以讀寫的方式打開test.txt檔案,檔案内容為"hello world"。在讀取檔案内容之後,向檔案test.txt中寫入"nihao world",關閉檔案後再讀取檔案。列印結果如下:
如上寫入之前test.txt内容為"hello world",寫入之後内容為"hello worldnihao world"。這是因為,在讀取檔案之後,檔案指針到達檔案末尾,寫入内容時,是從檔案末尾開始寫入的,是以寫入"nihao world"後為"hello worldnihao world"。如下圖形象的描述了這一過程:
再看如下例子:
fo.write("hi world")
這段代碼與之前代碼的不同就是,在往檔案中寫資料之前不會讀取檔案内容,同樣以讀寫的方式打開檔案test.txt,test.txt檔案内容為"hi world",寫入檔案的内容為"nihao world"。列印結果如下:
如上,在寫入檔案"hi world"後,檔案内容為"hi worldrld",這是因為在寫檔案之前并沒有讀檔案,是以是從檔案頭開始寫入的,實質上是"hi world"将"hello wo"這部分内容覆寫掉了。如下圖:
(4)讀寫檔案的常用方法
檔案對象fileObject有很多讀寫檔案的函數,調用這些函數可以高效友善的讀寫檔案。下面我們就一一介紹這些函數。
①函數readline(),調用fileObject.readline()在讀取檔案時,會以行為機關,逐行的讀取資料。每讀取一行就傳回一行的資料,直到傳回空字元,讀取結束。代碼如下:
lineStr=fo.readline()
while lineStr!='':
print(lineStr)
lineStr=fo.readline()
如上對test.txt逐行的讀取,直到讀取到的為空字元結束。test.txt中的資料如下:
②函數readlines(),調用fileObject.readlines(),也是逐行讀取檔案,但傳回時是把所有行封裝在清單中一次性傳回。代碼如下:
print(fo.readlines())
如上調用fileObject.readlines()讀取test.txt檔案。test.txt的資料如下:
代碼列印結果如下:
③writelines(List)
fileObject的函數writelines(List)的功能為将序列List中的元素逐個寫入檔案,這樣就可以一次性寫入大量的資料,當資料量較大時可以調用函數writelines(List)。如下:
fo=open("test.txt",'a')
l=['\none\n','two\n','three\n']
fo.writelines(l)
如上調用檔案對象fo的函數writelines(list)分别将清單l中的3個元素"\none\n","two\n","three\n"寫入test.txt中,test.txt檔案原内容為
,寫入後讀取結果如下:
④seek(offset,flag)
fileObject的一個控制檔案指針的函數為seek(offset,flag),offset為檔案指針移動的機關空間數,flag為标記位,控制着檔案指針移動的方式,傳回結果為一個整型資料,表示移動指針後指針所在的位置。具體的含義如下圖:
代碼例子如下:
fo=open("test.txt","rb")
print('the position is:',fo.seek(3,0))
print('the position is:',fo.seek(2,1))
print('the position is:',fo.seek(-2,2))
如上,分别使用3種方式控制檔案指針移動的方式,test.txt檔案的内容為"hello world",
先分析下如上代碼,fo.seek(3,0)表示檔案指針從檔案頭部後移3個機關,移完後檔案指針所在的位置為3,是以會傳回3;fo.seek(2,1)表示檔案指針從目前位置向後移動2個機關,目前位置是3,移動後檔案指針為5;fo.seek(-2,2),表示檔案指針從檔案末尾向後移動-2個機關,即向前移動2個機關,"hello world"總長度為11,向前移動2個機關,檔案指針位置為9.是以傳回的結果分别為:3,5,9.列印結果如下:
⑤flush()函數
當我們向檔案中寫資料時,是先将檔案内容寫入記憶體緩沖區,然後再将資料寫入檔案所在的硬碟上。有的時候系統為了避免多次通路硬碟降低讀寫的速度,會建立一定大小的緩沖區,等待資料充滿這個緩沖區再寫入硬碟。檔案對象fileObject的flush()函數功能為将記憶體緩沖區的資料立即寫入檔案,并清空緩沖區.如下代碼:
fo.write("12345")
fo.seek(0,0)#傳回檔案頭部
fo.flush()#将記憶體緩沖區的資料寫入檔案
print("after flush:",fo.read())
如上,調用fileObject.flush()将資料立即寫入檔案。代碼列印結果如下:
以上就是我們介紹的有關檔案操作的基礎,下一節我們将繼續介紹檔案目錄的相關操作,敬請期待。