1. 程式人生 > >Python 建立、讀取和寫入檔案以及yield關鍵字- 千月的python linux 系統管理指南學習筆記(14)

Python 建立、讀取和寫入檔案以及yield關鍵字- 千月的python linux 系統管理指南學習筆記(14)

無論是日誌檔案還是配置檔案都是我們日常運維中常見的型別,學習處理檔案的關鍵是學會如何處理文字資料。Python 包含一個稱為 file 的內建型別,可以用來處理檔案。 建立檔案物件 為了讀取一個現有的檔案,我們需要建立一個新的檔案物件,以用來對檔案進行互動。 open( ) 建立一個檔案物件 open( "檔名","模式",[緩衝區大小] ) #以指定模式對檔案互動 最普通的模式為 “r" 讀模式 為預設模式,還有 ”w“ 寫模式 ”a“ 附加模式 ”b“ 二進位制模式

我們先建立一個檔案作為互動物件。


read() 讀取檔案內容 這個讀取的方式是,從檔案頭讀取到檔案尾。 後面我們還會詳細討論讀檔案的方法。
write() 將文字寫入檔案 close() 將檔案關閉 這個寫入檔案,是覆蓋寫入,無論之前有什麼內容都會被覆蓋掉。 而且我們可以看例子,在寫入完畢後必須使用 close() 將檔案關閉。否則檔案並無內容。 當你要寫入檔案,資料並不會直接寫入檔案中,而是首先寫入到緩衝區, 等到緩衝區滿或者重新整理時,才將緩衝區的資料寫入到檔案中, 如果不這樣做會對磁碟 I/O 產生大量佔用,降低讀寫效率。 畢竟寫入緩衝區比寫入硬碟可快多了。
讀取檔案物件 read() 讀取檔案內容 檔案物件.read([size] ) #讀取全部或指定長度的檔案 我們讀取檔案,主要是為了取得檔案內的資料。我們先準備一個檔案。 這個例子看了會有幾個問題: 首先 \n 是換行符,並沒有翻譯成換行,而是如實的寫了出來。當然用 print 就沒這問題。 其次,我們在 read() 讀取了一次後,再次 read() 無法獲得任何字元。那是因為read是依靠指標來進行判斷是否到了檔案尾。 read() 一次後,指標到了檔案尾,再 read() 自然毫無返回。我們使用seek(0)將指標指回檔案頭。再次讀取就可以看到內容了,而2次 read(10)返回不同,更是證明了指標的存在。 readline() 讀取一行檔案內容
檔案物件.readline( [size] ) #讀取全部或指定長度的一行檔案 readlines() 按行的方式讀取全部檔案內容 這兩個命令很相似,readline 僅讀取一行,而 readlines 將全部檔案讀入並且組成一個按行分隔的列表。
我們在工作中希望以行為單位處理檔案的時候,一般情況下使用 readlines 。因為readlines 可以直接被 for ... in ... 結構使用。 我們嘗試給檔案的每一行前面加上一個 # 寫入檔案物件 write() 將文字寫入檔案 write() 寫入檔案在之前的建立環節已經研究過了,不再贅述。 當然如果你要在python環境下寫小說可以用 write() 慢慢寫,雖然文字編輯器會是更好的選擇。我們在運維工作中更多的還是基於行的寫入操作。比如固定格式的 Log 日誌,統計報表等。進行這樣的操作我們引入 writelines() writelines() 將文字序列寫入檔案
檔案物件.writelines( 文字序列 ) #將文字序列寫入檔案 尷尬的是雖然 writelines 直譯過來是 寫入行,但是事實上並不會為每個元素自動換行,我還是要加入 \n 的。或許叫做寫入元素更合適。 首先我們定義了一個叫 range1的函式,這個函式裡面帶有一個迴圈,而這裡使用 yield 這個關鍵字,使這個函式變成了一個 generator(生成器),從而使 writelines 呼叫的時候可以使用其迭代屬性,而迭代結束時丟擲的 StopIteration 異常,可以直接被捕獲,終止 writelines 。 如果感到理解起來有些吃力,可以自行搜尋下 yield 這個關鍵字。在運維過程中會經常用到,比如開啟一個巨大的檔案,又怕記憶體佔用不可預測而產生問題,可以通過 yield 避免。 舉一個簡單的 yield 讀取檔案的例子 主要是避免一次開啟大檔案而引起的未知記憶體佔用問題。我們分塊讀取。 我們定義了一個 read_file 函式,引數是檔案路徑。BLOCK_SIZE是定義了一次讀取的字元量。 在迴圈裡我們使用了 yield 使函式變為一個生成器。每次只讀取 10 位元組。 我們在引用的時候也要使用 for ... in ... 來輸出。為了清楚的看到效果,我用 print 來進行輸出。確實每次讀取10位元組。這樣避免一次讀取全部檔案而對記憶體造成無意義的過高佔用,使得記憶體佔用從未知變數變為已知常量。