從 JavaScript 角度學 Python(18) - 檔案處理

前言

接下來將會聊聊如何使用 Python 做到一些檔案處理的部分,例如:新增檔案、寫入資料到特定檔案內等方式。

檔案處理(File Handling)

Python 本身有支援檔案處理相關的函式,而檔案處理可以做到哪些事情呢?舉例一個情境好了。

假設今天我們寫了一隻爬蟲,然後去爬了特定網站(可能是 IT 邦幫忙),爬完之後你需要將資料儲存下來,那麼你就會需要使用到建立檔案與寫入檔案等等的行為。

所以檔案處理的相關知識就變得不能不了解囉~

聽到又要學新東西的你

那你可能會問說 JavaScript 可不可以做到類似檔案處理的部分呢?正常來講是不行的,除非…你使用的是 Node.js。

如果是使用 Node.js 的話,通常會使用 fs (File System) 模組來達到讀取與寫入等檔案操作的行為,例如:

1
2
3
4
5
var fs = require('fs');

fs.open('filename.txt', 'r+', function() {
console.log('檔案已開啟。')
})

而這邊並不著墨於 Node.js 的檔案存取部分,所以接下來會直接快速介紹 Python 的檔案模組部分,以便我們後面的學習唷~

open

這邊記得一件事情,只要跟 Python 檔案相關的操作,起手式是絕對閃不掉用 open() 函式,而 open() 很顧名思義就只是打開什麼東西的意思,所以這邊要注意 open() 只是要打開某個檔案的行為而已唷。

開始/讀取檔案

打開檔案之前要先注意到 open() 函式是一個表達式,所以會需要一個變數儲存,最主要原因是我們當我們打開了一個檔案之後,如果你不儲存的話,那你接下來要怎麼操作?

該怎麼操作

所以這邊要切記,當你呼叫了 open() 函式之後要記得用一個變數儲存,那麼 open() 主要是帶入兩個參數:

1
f = open('filename', 'mode')
  • filename
    • 檔案名稱 + 副檔名
  • mode
    • 檔案的模式

檔案名稱的部分只需要注意要加上副檔名,其他比較需要注意的是 mode 的部分,依據你傳入的參數不同就會得到不同結果,所以這邊就簡單列一下基本的 mode 參數:

參數 說明
r 以唯讀的方式開啟檔案
w 清除檔案內容後再寫入
a 開啟檔案後從檔案結尾寫入

這邊比較需要注意的是 open() 的意思就是「開啟檔案」,然後是用什麼方式處理。

那麼我們可以先嘗試撰寫以下程式碼並嘗試執行:

1
f = open('filename.txt', 'r')

基本上你有很高機會遇到以下錯誤訊息:

FileNotFoundError

1
FileNotFoundError: [Errno 2] No such file or directory: 'filename.txt'

因為這個檔案不存在所以才會發生該問題,這時候你可以自己建立一個 filename.txt 檔案,然後內容填寫以下:

1
Hello Python

filename

當你再次執行 Python 時,就不會出現任何錯誤,但是你可能會想說怎麼沒有輸出內容呢?就如同前面所講的,目前只是打開這個檔案,並沒有讀取,所以如果想要呈現內容的話就必須使用 read() 函式來讀取:

1
2
3
f = open('filename.txt', 'r')
read = f.read()
print(read)

這樣子就可以讀取出內容囉~

filename.txt

484 超直覺呢?

超直覺就是讚

這時候你可能會想說,你希望 filename.txt 這個檔案是自動生成的,而不是我們手動生成,這時候你是可以嘗試換另一種模式:

1
f = open('filename.txt', 'w')

或者是

1
f = open('filename.txt', 'a')

這兩種模式都可以達到「當檔案不存在時,就自動建立檔案」。

那麼這兩種模式有何差異呢?

w 模式下,如果檔案不存在就會新增檔案這一點沒問題,但是如果這個檔案存在的話,就會先清除檔案內容,這一點要特別注意一下。

a 模式則是會在開啟之後,從尾行開始寫入,這什麼意思呢?讓我們往後面練習會更清楚。

寫入檔案

那麼前面嘗試了開啟檔案並讀取檔案內容的行為,接下來就是關於寫入檔案的部分,否則你只打開跟讀取不寫入很怪吧?

只開不讀

不管怎麼樣,前面我們有講過只要跟檔案操作相關的行為就必定會有一個 open() 函式,所以前面就會有一個 open() 函式的起手式,前面也有講到依據你開啟檔案所傳入的參數模式的不同,而寫入方式就會跟著不同,那麼這是什麼意思呢?首先我們先看一下剛剛前面的範例程式碼:

1
2
3
f = open('filename.txt', 'r')
read = f.read()
print(read)

這一段程式碼執行之後結果就如同剛剛的圖片所示:

filename.txt

那麼我們期望打開檔案後寫入文字該怎麼做呢?

首先我們先假設我們想寫入兩段文字,分別是:「我是 Ray」、「部落格網址是 https://israynotarray.com/」這兩段文字,這時候就會使用到 write 的函式,但是在使用 write 之前有幾點注意事項要注意:

  • 寫入檔案時,必須為 a 或是 w 模式
  • 寫入檔案模式時,是不可以讀取內容的

如果你用 r 模式去開啟並嘗試寫入的話就會出現這一段錯誤訊息:

1
io.UnsupportedOperation: not writable

反之,如果你是在讀取模式嘗試寫入則會得到另一個錯誤訊息:

1
io.UnsupportedOperation: not readable

所以這邊就先嘗試使用 a 模式撰寫。

a 模式的特色就是開啟檔案後當你有寫入行為時,就會以檔案內容結尾處開始寫入,舉例來講,我目前 filename.txt 的內容如下:

1
Hello Python

那麼當我執行以下程式碼後:

1
2
3
4
f = open('filename.txt', 'a')
f.write('我是 Ray')
f.write('部落格網址是 https://israynotarray.com/')
f.close()

你再去打開 filename.txt 會得到以下結果:

filename

如果你期望的是斷行的話,只需要在程式碼尾端補上換行符號 \n 即可:

1
2
3
4
f = open('filename.txt', 'a')
f.write('我是 Ray\n')
f.write('部落格網址是 https://israynotarray.com/')
f.close()

filename

回頭講講 w 模式,w 模式簡單來講就是會先清除檔案內容才開始寫入。

舉例來講,目前的 filename.txt 內容如下:

1
2
3
Hello Python
我是 Ray
部落格網址是 https://israynotarray.com/

當我執行以下程式碼後,就會變了:

1
2
3
4
f = open('filename.txt', 'w')
f.write('我是 Ray\n')
f.write('部落格網址是 https://israynotarray.com/')
f.close()

filename

以我自己來講,我是比較常使用 a 模式就是了,畢竟 w 模式會先將內容清空後再寫入,如果沒有把這兩種模式搞清楚的話,你可能會發生為什麼檔案一直被清空的狀況。

懷疑人生

追加模式

最後我想補充一個東西,叫做追加模式,上面我們聊了許多檔案處理相關的方式,其中也包含了寫法與運作說明,那麼其實 open 函式的開啟 mode 還有其他模式可以使用,而這些模式稱之為「追加模式」。

使用的方式非常的簡單,只需要加上一個 + 號就可以改變原有的模式。

舉例來講,前面我們有講到 r 代表的是唯讀開啟,因此無法寫入,但是當你使用了追加模式 r+,那麼此時就會變成讀寫皆可的狀態,意指同時可以寫入與讀取檔案。

什麼意思呢?這邊簡單舉例一個範例:

1
2
3
4
f = open('filename.txt', 'r+')
f.write('我是 Ray\n')
f.write('部落格網址是 https://israynotarray.com/')
f.close()

這一段程式碼是可以正常執行並不會出現 io.UnsupportedOperation: not writable 的。

而其他的 wa 模式也可以使用 + 號追加模式,但實際上我測試下來 w+a+ 並沒有太大差異,畢竟一個依然是清除檔案內容在寫入與在檔案結尾寫入,實際上比較有差異的就是 r 模式,所以就不再額外補充囉。

那追加模式的使用時機並沒有絕對,還是要看需求為主哩。

我被你搞得好亂RRR

作者的話

今天狗狗狀況整個大翻轉,一覺醒來開始會耍白目,雖然有點煩,但是這樣子才是牠應該要有的樣子。

關於兔兔們

兔法無邊

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ