(Python)-初學 Class-12 — 檔案處理

(Python)-初學 Class-12 — 檔案處理

(Python)-初學 Class-12 — 檔案處理

利用程式進行讀/寫檔案的處理

 

 

在撰寫程式的過程當中,目前為止我們大多是使用鍵盤來進行輸入( input() 函式),或是利用螢幕本身的 console 輸出(搭配 print() 函式)來處理輸入輸出。

然而,我們並不可能總是使用鍵盤來進行輸入,假如今天的輸入值太多、或是我們要處理的是一些已經存在的數據,利用鍵盤輸入就顯得十分不效率;相對的,我們得到程式的輸出值以後,如果要將結果傳給其他人,那麼使用螢幕輸出就不會是一個好方法。

因此,這時我們所需要的,就是檔案處理的方法。

 

12-1 開啟以及關閉檔案

當我們今天想要來處理檔案,首先要先讓電腦知道現在我們所要處理的檔案是哪一份檔案。此時我們所使用的方法如下:

 

f = open(檔名, mode)

 

12-1-1 檔案物件 file object

此時變數 f 被 assign 的是一個 file object,所謂的 file object 的說明如下:

A file object allows us to use, access and manipulate all the user accessible files. One can read and write any such files. — — GeeksforGeeks

也就是說, file object 就是一個 Python 當中的物件,提供許多函式、方法讓我們處理任意的檔案。

 

12-1-2 開啟檔案 open()

 

open(file, mode=’模式’)

 

在這裡所用到的函式 open() 的部分通常包含兩個參數,檔案名稱以及模式 mode 。

檔名所要填入的是檔案路徑,指的是相對路徑,也就是相對於你的程式執行的位置而言,你的檔案在什麼地方。如果在同一個資料夾當中執行,可以直接寫檔案的名稱,如 “test.txt” 。

而 mode 代表的是你開啟檔案的模式,Python 提供了數種開啟檔案的模式,包含僅供讀取、可以覆寫檔案等等。以下將對於其中三種稍作簡介:

 

“r” 唯讀模式:當我們以 mode 為 “r” 開啟檔案時,意即我們只能從指定的檔案讀取資料,並不能夠對這個檔案的內容進行更動。與此同時,如果我們所指定的檔案不存在,將會產生 FileNotFoundError 的例外。

“w” 寫入模式(覆寫):而如果我們以 “w” 為開啟檔案的模式時,意即要來進行檔案的寫入,會在開啟的位置直接覆蓋掉原本的檔案。如果我們所指定的檔案路徑/名稱不存在,會新增一個新的檔案。

“a” 寫入模式(續寫):但若我們設定開啟檔案的模式為 “a”,是指在此模式下開啟檔案要進行寫入時,會從原本的檔案最後繼續進行寫入。

 

12-1-3 關閉檔案 close()

當我們在程式當中開啟了檔案以後,如果要停止對於這個檔案的更動或寫入,可以將檔案關閉。此時所使用的函式如下:

 

f.close()

 

當我們要開啟其他檔案時,當然可以直接再開啟然後取代掉目前的 file object,但是記得在使用時關閉檔案依然是一個好習慣。

 

讀取檔案

接著,當我們成功開啟檔案以後,下一個要做的就是將檔案當中的資料讀取進來。Python 在 file object 當中提供了數種從檔案讀取資料的方法,供大家做選擇使用,以下將對於幾種不同的用法稍作簡介。

 

1. file.read()

第一種是 f.read() 函式,用法如下:

 

file.read([size])

 

括號當中的參數 size 是 optional 的,當我們設置了 size 的值,電腦就會自動讀到指定的字節數量,若沒有設置就會將整個檔案都讀取進來。

舉例來說,當我們今天有一個叫做 file_io.txt 的文字檔,內容如下:

 

I love Python! KK number one!

 

我們嘗試使用 f.read() 來讀取資料,並且嘗試以下兩種不同的讀取方式:

 

words = f.read()

print(words)

I love Python! KK number one!

 

以及

 

word = f.read(6)

print(word)

 

分別以有無限制讀取字節數量的方法進行讀取,執行結果如下:

 

Learn 1 :

f = open ("file_io.txt", "r")

words = f.read()

print(words)

f.close()

I love Python! KK number one!

——

f = open("file_io.txt", "r")

word = f.read(6)

print(word)

f.close()

I love

可見,當我們執行的是 f.read(6) ,我們所讀取到的內容為 I love ,共六個字節;但當我們執行 f.read() 時,讀取到的即是完整的資料內容: I love Python\n KK number one! 。

 

2. file.readline()

另一種方法是 f.readline() ,他所做的事情跟這個函式的命名相同,就是將讀取檔案中的整行資料,但是一次只讀取一行,包含 \n 字元,如果檔案當中包含了 N 行的資料,我們就必須呼叫 f.readline() N 次。

我們再一次讀取剛才的文字檔 file_io.txt ,並且將兩行內容輸出。為了證明 f.readline() 真的只會讀取一行,我們將輸出順序顛倒:

 

first_line = f.readline()

second_line = f.readline()

print(second_line, first_line, sep = "\n")

 

執行結果如下:

Learn 2 :

f = open("file_io.txt", "r")

first_line = f.readline()

second_line = f.readline()

print(second_line, first_line, sep = "\n")

f.close()

KK number one! I love Python!

 

3. file.readlines()

除了逐行讀取,Python 也提供一次讀取所有資料的方法:

 

f.readlines()

f.readlines() 會將檔案當中的所有資料都逐行讀取進來,然後會將其回傳成為一個 list ,我們嘗試執行以下的程式碼,將檔案使用 f.readlines() 讀取進來以後,用變數 k 接住,然後將其印出以便查看:

 

Learn 3 :

f = open('file_io.txt')

k = f.readlines()

print(k)

f.close()

 

執行結果如下:

[“I love Python!\n”, “KK number one!”]

 

由此可見, f.readlines() 會將檔案當中每一行當作是一個字串,然後存進串列當中回傳。因此 for loop經常與 f.readlines() 搭配使用,方法如下:

 

for line in f.readlines():

    print(line)

 

執行結果如下,由於當 f.readlines() 將每一行的文字讀取進來時,會連換行符號的 \n 一起讀進來,因此,在使用 print() 將其印出時,會有原本字串當中的 \n 以及 print() 本身預設的 end 字元 \n ,所以中間會出現空行:

 

Learn 4 :

f = open("file_io.txt")

for lines in f.readlines():

    print(lines)

f.close()

除此之外, Python 還給了我們一個幾乎一模一樣的用法,在不使用 f.readlines() 的情況下,我們可以直接利用 for loop 對於我們的 file object f 來 iterate,方法如下:

 

f = open('file_io.txt')

for line in f:

    print(line)

f.close()

 

我們會得到相同的執行結果:

 

Learn 5 :

f = open("file_io.txt")

for line in f:

    print(line)

f.close()

I love Python! KK number one!

 

12-2-1 寫入檔案

講完如何讀取檔案,接著將介紹該如何將資料寫入檔案。與讀取相同,Python 同樣也提供了幾種不同的輸出方式:

 

1. file.write()

 

第一種是 f.write() ,其概念相對於剛才所介紹的 f.read() ,參數的資料型態是字串 string ,在使用上也相當容易:

舉例的程式碼如下:

 

Learn 6 :

f = open('file_io.txt', 'w')

f.write("Try to use file.write()\nHail HYDRA")

f.close()

 

執行以上的程式碼,將會得到一個新的檔案內容:

Try to use file.write() Hail HYDRA

現在檔案的內容完全就是剛才我們作為 f.write() 參數的字串。

 

2. file.writelines()

當然,如果你不想要每輸出一段東西就使用一次 f.write() ,Python 也提供了另一個概念和 f.readlines() 相對的函式:

 

f.writelines() 用法如下:

file.writelines(seq)

 

這裡的參數 seq 指的是 f.writelines() 的參數必須是一個序列,也就是 list 或是 tuple 這類的資料型態。而 f.writelines() 就會將你所給的 sequence 當中的內容印出,舉例來說,假如我們今天想要輸出和上面相同的檔案,我們可能的寫法如下:

 

Learn 7 :

f = open('file_io.txt', 'w')

seq = ["Try to use file.write()\n","Hail HYDRA"]

f.writelines(seq)

f.close()

而執行上面的程式碼,我們將會得到如下的文字檔:

 

Try to use file.write() Hail HYDRA

 

由此可見,雖然 f.writelines() 會將我們所給的參數 sequence 當中的內容一個一個印出,卻不會像 print() 一樣預設在輸出的東西後面附上換行 \n ,因此,我們必須在要換行的字串中自行加上 \n 。

 

3. print()

當然,貼心的 Python 也提供了我們利用熟悉的 print() 就可以完成輸出到檔案的方法。當我們今天想要將任何東西輸出時,都會直接使用 print() ,然後頂多更改參數 sep 或是 end 。然而,除了這兩個參數以外,還有第三個參數 file 。

舉例來說,我們今天有一個 list 叫做 movielist ,內容如下:

 

Learn 8 :

movielist=["The Shawshank Redemption", "The Godfather", "The Dark Knight", "12 Angry Men", "Schindler's List", "The Lord of the Rings: The Return of the King", "Pulp Fiction", "Fight Club"]

print(movielist)

[‘The Shawshank Redemption’, ‘The Godfather’, ‘The Dark Knight’, ’12 Angry Men’, “Schindler’s List”, ‘The Lord of the Rings: The Return of the King’, ‘Pulp Fiction’, ‘Fight Club’]

然而,當我們設定了 file 這個參數以後,將程式碼改成下方的樣子,就不一樣了:

 

Learn 9 :

f = open('movies.txt','w')

print(movielist, file = f)

f.close()

 

[‘The Shawshank Redemption’, ‘The Godfather’, ‘The Dark Knight’, ’12 Angry Men’, “Schindler’s List”, ‘The Lord of the Rings: The Return of the King’, ‘Pulp Fiction’, ‘Fight Club’]

 

我們得到了一個裝著和方才直接使用 print() 時一樣內容的 txt 檔案。

在檔案中移動位置

接著,我們要來介紹如何更進一步的進行檔案的處理。當我們在進行檔案的讀取時,有時可能會想要將檔案從頭到尾讀取第二遍。

假設今天有一個文字檔叫做 sample.txt ,內容如下:

123 456 789

那麼,當我們想要將上面的檔案內容印出兩次時,可能會寫出如下的程式碼進行以下的操作:

 

Learn 10 :

f = open('sample.txt')

for line in f:

    print(line)

for line in f:

    print(line)

f.close()

 

在我們的想像當中,上面的程式碼在第一個 for loop 跑完以後,下一個 for loop 應該要將檔案的內容在輸出一次,也就是說,我們心裡想的輸出結果應該要是這樣子的:

 

123 456 789 123 456 789

 

然而,執行結果卻如下:

123 456 789

 

很顯然的,第二次的 for loop 完全沒有印出東西來。

原因是這樣子的,當我們在讀取或是寫入檔案時,可以想像成電腦裡面有一個指標,類似於我們在使用 word 或是任何的文字編輯器時的指標,我們會依照他的位置,知道我們接下來如果要打字會出現在什麼地方。

同樣的,當 file object 在處理檔案時也是一樣的概念。在上面的範例當中,第一個 for loop 結束以後,這個指針隨著我們的讀取已經到了文件的最後面。因此,接下來想要再使用 for loop 來讀取的話,如果我們沒有將指針移到檔案最前面,就無法得到任何東西。因此,以下要介紹用來移動這個指針或是獲取現在指針位置的方法。

 

4. file.seek()

第一個是 f.seek() ,顧名思義,就是在檔案當中尋找。不過這裡說的尋找指的並不是尋找某個字或是某個資料,而是尋找某個位置,用法如下。

file.seek()

我們繼續使用上面的例子,此時,若我們想要將檔案的內容完整輸出兩次,只需要在兩個 for loop 之間加上一行 f.seek(0) 即可:

 

Learn 11 :

f = open('sample.txt')

for line in f:

    print(line)

f.seek(0)

for line in f:

    print(line)

f.close()

 

執行結果如下圖:

123 456 789 123 456 789

 

也就是說,當我們想要移動這個指針的位置,只要使用 f.seek() 就可以將指針移到目標位置。所以當我們將 f.seek() 當中的參數設為 1 時,就會輸出下面的結果:

 

Learn 12 :

f = open("sample.txt")

f.seek(1)

for line in f:

    print(line)

23 456 789

 

可以看出,當我們寫 f.seek(1) 時,將會移到文件當中的位置一。所以當我們在讀取時,會從第二個字元開始讀取。

需要注意的是,如果檔案內容有中文字,可能就需要去更改檔案開啟時的編碼方式等等,在此便不贅述。

 

5. file.tell()

最後,我們要來介紹的是 f.tell() 。他和 f.seek() 接近於相對的概念,所謂的 f.tell() ,顧名思義就是會回傳給你現在指標所在的位置。

為了舉例方便,我們同樣使用方才的 sample.txt ,內容如下:

 

123 456 789

 

如果我們今天在讀取資料時使用的是 f.read() 時,我們可以很輕鬆地知道目前指針的位置在哪裡。然而,若我們想要搭配 f.seek() 或是其他方法使用時,就需要知道目前確切的指針位置,與此同時也可以知道目前進行到檔案的什麼地方。

舉例來說,當我們今天先使用了 f.read() 又使用了 f.readline() 時,可能會想要知道接下來會從哪個位置開始。試寫程式碼如下:

 

Learn 13 :

f = open('sample.txt')

print(f.read(1))

print(f.readline())

print(f.tell())

f.close()

1 23

4

由此可見,使用 f.tell() 可以得到目前指針所在的位置,是下一行的開頭也就是 123\n 之後的位置 4。

 

小結

本篇簡介了許多檔案處理相關的方法,雖然是以 txt 檔為介紹範例,但是對於其他檔案也是可以使用的,最多就是依照目標檔案的編碼格式進行調整。

 

當然,針對不同的檔案格式, Python 也有許多集前人智慧的好用 module 可以使用,這個就稍待之後再來進行介紹。

 

免責聲明:

1.本影像檔案皆從網上搜集轉載,不承擔任何技術及版權問題

2.如有下載連結僅供寬頻測試研究用途,請下載後在24小時內刪除,請勿用於商業

3.若侵犯了您的合法權益,請來信通知我們,我們會及時刪除,給您帶來的不便,深表歉意。

 



發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *