課時28:檔案:因為懂你,所以永恆

那是個好男孩發表於2018-08-20

目錄:

  一、開啟檔案

  二、檔案物件的方法

  三、檔案的關閉

  四、檔案的讀取和定位

  五、檔案的寫入

  六、課時28課後習題及答案

 

大多數程式都遵循著:輸入->處理->輸出的模型,首先接受輸入資料,然後按照要求進行處理,最後輸出結果。現在我們不再只滿足使用input接受使用者的輸入,使用print輸出處理的結果了。我們迫切想要關注到系統的方方面面,用程式碼自動分析系統的日誌,分析的結果可以儲存為一個新的日誌,甚至可以跟外面的世界進行交流。

在編寫程式的時候,作業系統為了更快的做出響應,把所有當前的資料都放在記憶體中。但記憶體有個天生的不足,一斷點就沒戲,emmmm。ctrl + s 學起,儲存資料!

****************

一、開啟檔案

****************

在Python中,使用open()這個函式來開啟檔案並返回檔案物件:help(open)

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

open()這個函式是有很多引數的,但作為初學者的我們,只需要先關注第一個引數和第二個引數即可。第一個引數是傳入的檔名,如果只有檔名,不帶路徑的話,那麼python會在當前資料夾中去找到該檔案並開啟。如果要開啟的檔案不存在呢?那就要看第二個引數了,第二個引數指定開啟檔案的模式:

開啟模式      執行操作
'r'            以只讀方式開啟檔案(預設)
'w'            以寫入的方式開啟檔案,會覆蓋已存在的檔案
'x'            如果檔案已經存在,使用此模式開啟將引發異常
'a'            以寫入模式開啟,如果檔案存在,則在末尾追加寫入
'b'            以二進位制模式開啟檔案
't'            以文字模式開啟(預設)
'+'            可讀寫模式(可新增到其他模式中使用)
'U'            通用換行符支援

使用open成功開啟一個檔案後,它會自動返回一個檔案物件,拿到這個檔案物件,就可以讀取或者修改這個檔案:

>>> #先將record.txt檔案放到Python的根目錄下(如:C:\Python34)
                              
>>> f = open("record.txt")
                              
>>> 

沒有訊息就是好訊息,表示我們的檔案被成功開啟了。

***********************

二、檔案物件的方法

***********************

開啟完檔案並取得檔案物件之後,就可以利用檔案物件的一些方法對檔案進行讀取或修改等操作。如下表列舉了一些檔案物件的方法:

檔案物件方法                  執行操作
f.close()                      關閉檔案
f.read([size=-1])           從檔案讀取size個字元,當未給定size或給定負值的時候,讀取剩餘的所有字元,然後作為字串返回
f.readline([size=-1])        從檔案中讀取並返回一行(包括行結束符),如果有size有定義則返回size個字元
f.write(str)                   將字串str寫入檔案
f.writelines(seq)           向檔案寫入字串序列seq,seq應該是一個返回字串的可迭代物件
f.seek(offset, from)          在檔案中移動檔案指標,從from(0代表檔案起始位置,1代表當前位置,2代表檔案末尾)偏移offset個位元組
f.tell()                返回當前在檔案中的位置
f.truncate([size=file.tell()])  擷取檔案到size個位元組,預設是擷取到檔案指標當前位置
                

  

******************

三、檔案的關閉

******************

close()方法用於關閉檔案。Python擁有垃圾回收機制,會在檔案物件的引用計數降至零的時候自動關閉檔案,所以在Python程式設計裡,如果忘記關閉檔案並不會造成記憶體洩露那麼危險的結果。

但並不是說就可以不關閉檔案,如果你對檔案進行了寫入操作,那麼應該在完成寫入之後關閉檔案。因為Python可能會快取你寫入的資料,如果中途發生類似斷電之類的事故,那麼快取的資料根本就不會寫入到記憶體中。所以,安全起見,要養成使用完檔案後立刻關閉的好習慣。

**************************

四、檔案的讀取和定位

**************************

檔案的讀取方法有很多種,可以使用檔案物件的read()和readline()方法,也可以直接list(f)或者直接使用迭代來讀取。read()是按位元組為單位讀取,如果不設定引數,那麼會全部讀取出來,檔案的指標指向末尾。tell()方法可以告訴你當前檔案指標的位置:

>>> f.read()
                              
'小客服:小甲魚,今天有客戶問你有沒有女朋友?\n小甲魚:咦??\n小客服:我跟她說你有女朋友了!\n小甲魚:。。。。。。\n小客服:她讓你分手後考慮下她!然後我說:"您要買個優盤,我就幫您留意下~"\n小甲魚:然後呢?\n小客服:她買了兩個,說發一個貨就好~\n小甲魚:呃。。。。。。你真牛!\n小客服:那是,誰讓我是魚C最可愛小客服嘛~\n小甲魚:下次有人想調戲你我不阻止~\n小客服:滾!!!\n================================================================================\n小客服:小甲魚,有個好評很好笑哈。\n小甲魚:哦?\n小客服:"有了小甲魚,以後媽媽再也不用擔心我的學習了~"\n小甲魚:哈哈哈,我看到丫,我還發微博了呢~\n小客服:嗯嗯,我看了你的微博丫~\n小甲魚:喲西~\n小客服:那個有條回覆“左手拿著小甲魚,右手拿著打火機,哪裡不會點哪裡,so easy ^_^”\n小甲魚:T_T\n================================================================================\n小客服:小甲魚,今天一個會員想找你\n小甲魚:哦?什麼事?\n小客服:他說你一個學生月薪已經超過12k了!!\n小甲魚:哪裡的?\n小客服:上海的\n小甲魚:那正常,哪家公司?\n小客服:他沒說呀。\n小甲魚:哦\n小客服:老大,為什麼我工資那麼低啊??是時候漲漲工資了!!\n小甲魚:啊,你說什麼?我在外邊呢,這裡好吵吖。。。。。。\n小客服:滾!!!'
>>> f.tell()
                              
1129

剛才提到的檔案指標是啥?可以認為它是一個”書籤“,起到定位的作用。使用seek()方法可以調整檔案指標的位置。seek(offset,from)方法有兩個引數,表示從from(0代表檔案的起始位置,1代表當前位置,2代表檔案末尾)偏移offset位元組。因此將檔案指標設定到起始位置,使用sek(0,0)即可:

>>> f.tell()
                              
1129
>>> f.seek(0,0)
                              
0
>>> f.read(5)
                              
'小客服:小'
>>> f.tell()
                              
9

(注:因為一箇中文字元佔用2個位元組的空間,所以4箇中文加上1個英文冒號剛好到位置9)

readline()方法用於在檔案中讀取一整行,就是從檔案指標的位置向後讀取,直到遇到換行符(\n)結束:

>>> f.readline()
                              
'甲魚,今天有客戶問你有沒有女朋友?\n'

此前介紹過列表的強大,這不,也可以將整個檔案的內容放在列表中:

>>> list(f)
                              
['小甲魚:咦??\n', '小客服:我跟她說你有女朋友了!\n', '小甲魚:。。。。。。\n', '小客服:她讓你分手後考慮下她!然後我說:"您要買個優盤,我就幫您留意下~"\n', '小甲魚:然後呢?\n', '小客服:她買了兩個,說發一個貨就好~\n', '小甲魚:呃。。。。。。你真牛!\n', '小客服:那是,誰讓我是魚C最可愛小客服嘛~\n', '小甲魚:下次有人想調戲你我不阻止~\n', '小客服:滾!!!\n', '================================================================================\n', '小客服:小甲魚,有個好評很好笑哈。\n', '小甲魚:哦?\n', '小客服:"有了小甲魚,以後媽媽再也不用擔心我的學習了~"\n', '小甲魚:哈哈哈,我看到丫,我還發微博了呢~\n', '小客服:嗯嗯,我看了你的微博丫~\n', '小甲魚:喲西~\n', '小客服:那個有條回覆“左手拿著小甲魚,右手拿著打火機,哪裡不會點哪裡,so easy ^_^”\n', '小甲魚:T_T\n', '================================================================================\n', '小客服:小甲魚,今天一個會員想找你\n', '小甲魚:哦?什麼事?\n', '小客服:他說你一個學生月薪已經超過12k了!!\n', '小甲魚:哪裡的?\n', '小客服:上海的\n', '小甲魚:那正常,哪家公司?\n', '小客服:他沒說呀。\n', '小甲魚:哦\n', '小客服:老大,為什麼我工資那麼低啊??是時候漲漲工資了!!\n', '小甲魚:啊,你說什麼?我在外邊呢,這裡好吵吖。。。。。。\n', '小客服:滾!!!']

對於迭代讀取文字檔案中的每一行,也許會這樣寫:

>>> f.seek(0,0)
                              
0
>>> lines = list(f)
                              
>>> for each_line in lines:
       print(each_line)

這樣寫沒有錯,但是效率不高。因為檔案物件本身是支援迭代的,所以沒必要繞圈子,直接使用for語句把內容迭代讀取出來即可:

>>> f.seek(0,0)
                              
0
>>> for each_line in f:
        print(each_line)

                              
小客服:小甲魚,今天有客戶問你有沒有女朋友?

小甲魚:咦??

小客服:我跟她說你有女朋友了!

小甲魚:。。。。。。

小客服:她讓你分手後考慮下她!然後我說:"您要買個優盤,我就幫您留意下~"

小甲魚:然後呢?

小客服:她買了兩個,說發一個貨就好~

小甲魚:呃。。。。。。你真牛!

小客服:那是,誰讓我是魚C最可愛小客服嘛~

小甲魚:下次有人想調戲你我不阻止~

小客服:滾!!!

================================================================================

小客服:小甲魚,有個好評很好笑哈。

小甲魚:哦?

小客服:"有了小甲魚,以後媽媽再也不用擔心我的學習了~"

小甲魚:哈哈哈,我看到丫,我還發微博了呢~

小客服:嗯嗯,我看了你的微博丫~

小甲魚:喲西~

小客服:那個有條回覆“左手拿著小甲魚,右手拿著打火機,哪裡不會點哪裡,so easy ^_^”

小甲魚:T_T

================================================================================

小客服:小甲魚,今天一個會員想找你

小甲魚:哦?什麼事?

小客服:他說你一個學生月薪已經超過12k了!!

小甲魚:哪裡的?

小客服:上海的

小甲魚:那正常,哪家公司?

小客服:他沒說呀。

小甲魚:哦

小客服:老大,為什麼我工資那麼低啊??是時候漲漲工資了!!

小甲魚:啊,你說什麼?我在外邊呢,這裡好吵吖。。。。。。

小客服:滾!!!

 

******************

五、檔案的寫入

******************

如果要寫入檔案,請確保之前的開啟模式有‘w’或‘a’,否則會出錯:

>>> f = open("record.txt")
                              
>>> f.write("這是一段待寫入的資料")
                              
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    f.write("這是一段待寫入的資料")
io.UnsupportedOperation: not writable
>>> f.close()
                              
>>> f = open("record.txt","w")
                              
>>> f.write("這是一段待寫入的資料")
                              
10
>>> f.close()

然而,一定要注意的是:使用‘w’模式寫入檔案,此前的檔案內容會被全部清除!!如下圖:

 

*******************************

六、課時28課後習題及答案

*******************************

 

相關文章