檔案操作

要把操作之資料記錄下來,除了資料庫之外,其實最簡單的方式是使用Python的檔案操作,使用簡單的指令直接對磁碟裝置進行開檔、新增資料、關檔。

列出檔案目錄

在操作檔案之前,可以先使用以下的命令來列出目前的目錄中所有的檔案列表:

>>> import os
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb']

os.listdir()會傳回一個串列,其中就包含了所有目前中的檔案,想要顯示目前的檔案數量,只要如前面在介紹串列的操作中所使用的len函數一樣,透過 len來計算串列的長度,就等於是知道了目前目錄中的檔案數量。

>>> import os
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb']
>>> n = len(os.listdir())
>>> print("There are {} files in this directory!".format(n))
There are 2 files in this directory!

建立資料夾

os模組除了列出檔案名稱之外,也可以透遇mkdir來建立資料夾,操作如下:

>>> os.mkdir("data")
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb', 'data']

寫入檔案

要寫入檔案需要先指定檔案名稱,然後執行開始檔案,再把開啟後的結果放在一個變數物件中,之後就可以透過該指標對這個檔案進行存取,結束不使用之後再把檔案關閉即可。以下是一個開啟檔案,寫入一個字串之後再把檔案關閉的程式範例:

>>> fp = open("mydata.txt", "wt")
>>> fp.write("This is my data!\n")
17
>>> fp.close()
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb', 'data', 'mydata.txt']

請注意,在第2行的字串中最後面那個「\n」的符號是換行記號,沒有這行的話,後面的資料會被串接在這一行的後面。

在開啟檔案的時候,檔案名稱後面那個參數就是用來指定要對檔案存取的方式,有以下幾種可用的指示元:

mode

說明

r

讀取

a

附加資料到檔案中

w

寫入

x

建立檔案

其中,如果w和a最大的差別在於是否需要保留原有檔案中的資料,如果使用w的話,會把原有的檔案資料清掉重寫,而a則會讓新的資料附加在原有的資料的後面。以下的例子是使用a來開啟之前的檔案,再寫入一些資料的例子:

>>> fp = open("mydata.txt", "a")
>>> fp.write("This is 2nd line!\n")
18
>>> fp.close()

在上面的4個指字元之後還可以再選擇以下的兩種其中之一,特別說明要存取的資料是何種型式:

模式

說明

t

文字模式,這也是預設的模式

b

二進位模式,主要是為了處理非可讀取的二進元檔案,如圖形檔等格式

一般來說我們都只要使用預設的模式,以文字檔的方式來存取資料就可以了。

從檔案中讀取資料

在前述的程式中寫入的文字資料,要如何才能夠把它讀取出來呢?同樣也是使用open函數開啟檔案,在取得檔案物件之後,就可以利用read, readline, readlines來讀取檔案中的資料,此三個函數主要的差異在如下表所列:

函數名稱

說明

read

一次讀取檔案中的所有資料

readline

一次讀取檔案中的一行資料

readlines

一次讀取檔案中的資料,但是把資料分成一列列,逐列放到串列資料結構中

以下的程式是把之前的檔案都讀取出來之後的比較:

fp = open("mydata.txt")
print(fp.read())
fp.seek(0)
print(fp.readline())
fp.seek(0)
print(fp.readlines())
fp.close()

第3行、第5行的seek是用來調整目前要讀取的資料的指標位置用的,seek(0)就表示要回到檔案的最前面。

以下是程式輸出的結果:

This is my data!
This is 2nd line!
This is my data!
['This is my data!\n', 'This is 2nd line!\n']

同學們可以看得出來差別了嗎?

with的用法

因為每一次使用檔案都要開檔和關檔,如果這個檔案打開之後只做了一些事就要關檔,並不會在其它的地方繼續使用的話,使用with可以簡化一些程序,也避免檔案打開之後就忘記關閉的情形,前面的程式如果使用with的話,可以改寫如下:

with open("mydata.txt") as fp:
print(fp.read())
fp.seek(0)
print(fp.readline())
fp.seek(0)
print(fp.readlines())

改完之後功能是一樣的喔。