iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
Software Development

跟著 OXXO 一起學 Python系列 第 28

( Day 14.1 ) Python 內建函式 ( 檔案讀寫 open )

  • 分享至 

  • xImage
  •  

本篇教學會介紹「檔案讀寫」的內建函式 open,透過 Pythen 的 open 函式,就能針對電腦中的文件,進行新增、開啟、編輯等動作,如果是使用 Google Colab,更可以和 Google 雲端硬碟連動,編輯雲端硬碟的檔案。

原文參考:內建函式 ( 檔案讀寫 open )

本篇使用的 Python 版本為 3.7.12,所有範例可使用 Google Colab 實作,不用安裝任何軟體 ( 參考:使用 Google Colab )

使用 open()

Python 內建的 open() 使用的語法如下所示,檔案表示檔案的路徑和檔名,模式則代表開啟檔案後,能對這個檔案編輯的權限模式,預設為 r。

f = open('檔案', 模式)

open() 還有幾個可以不需要填入的參數,不填入則會使用預設值:

參數 說明
newline 換行模式,預設 None ( 使用通用換行符號,等同 '' ),可以是 ''、'\n'、'\r' 或 '\r\n'。
encoding 解碼或編碼文件名稱,預設 None。
errors 處理解碼或編碼時的錯誤,預設 None。
buffering 記憶體緩衝區大小,預設 -1。
closefd 判斷文件名稱或文件描述,預設 True。
opener 文件描述,預設 None。

檔案路徑

檔案的路徑使用「相對路徑」,相對於「執行這個 Python 程式的位置」,例如 Python 的程式位在 file 資料夾下,要存取 file/demo 資料夾內的 test.txt 檔案時,路徑就是「demo/test.txt」。

f = open('demo/test.txt','r')
a = f.read()
print(a)
f.close()

Python 教學 - 內建函式 ( 檔案讀寫 open ) - 檔案路徑

如果是使用 Google Colab,預設執行的路徑放在「/content/drive/MyDrive/」裡。

f = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
a = f.read()
print(a)
f.close()

Python 教學 - 內建函式 ( 檔案讀寫 open ) - Colab 預設路徑

存取模式

使用 open() 開啟檔案時,可指定開啟後檔案的存取模式,預設是文字模式開啟,後方如果有「+」號,表示在功能上不僅可以讀取,也可以寫入:

模式 說明
rrt 讀取檔案 ( 預設值,檔案必需存在 )。
wwt 寫入檔案 ( 如果檔案不存在,就建立新檔案,如果檔案存在,則清空內容並將其覆寫 )。
xxt 建立新的檔案 ( 只針對不存在的檔案,如果檔案已經存在,則操作失敗 )。
aat 從檔案的最末端添加內容 ( 如果檔案不存在,就建立新檔案 )。
r+rt+ 讀取並更新檔案 ( 更新方式從最前端寫入內容 )。
w+wt+ 寫入並讀取檔案 ( 會清空並覆寫內容 )。
a+at+ 從檔案的最末端添加內容並讀取檔案。

如果後方加上 b,則會以二進制模式開啟:

模式 說明
rb 以二進制模式讀取檔案。
wb 以二進制模式寫入檔案。
xb 以二進制模式建立一個新的檔案。
ab 以二進制模式從檔案的最末端添加內容。
rb+ 以二進制模式讀取並更新檔案。
wb+ 以二進制模式寫入並讀取檔案。
ab+ 以二進制模式從檔案的最末端添加內容並讀取檔案。

舉例來說,如果開啟檔案時模式設定為 w,就無法使用讀取的方法讀取檔案內容。

f = open('/content/drive/MyDrive/Colab Notebooks/test.txt','w')   # 使用 w 模式
a = f.read()   # 發生錯誤  not readable
print(a)

如果開啟檔案時設定 r+,則可以讀取內容也可以從開頭的地方加入內容 ( 使用 r 或 r+ 時,檔案必需存在,不然會發生錯誤 )。

f = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r+')
a = f.read()
f.write('hello')
print(a)
f.close()

操作方法

開啟檔案後,可以透過下列常用的方法操作檔案:

方法 說明
read(size) 讀取檔案內容,預設不設定 size,不設定 size 會讀取整個檔案,如果設定 size 則會讀取指定的字元數量。
readline(size) 讀取檔案的第一行內容,預設不設定 size,沒有設定 size 就會讀取一整行,如果設定 size 則會讀取指定的字元數量。
readlines(size) 讀取檔案內容並以串列方式回傳,預設不設定 size,如果沒有設定 size 會讀取全部內容,如果設定 size 則會回傳包含 size 大小的那幾行。
readable() 檔案是否可讀取,回傳 True 或 False。
write(文字內容) 寫入內容。
writelines(文字內容串列) 以串列方式寫入內容,如果需要換行必須自行加入換行符號 \n。
writable() 檔案是否可寫入,回傳 True 或 False。
tell() 回傳目前讀取檔案指針的位置 ( 檔案從頭算起的字元數)。
seek(偏移量, 起始位置) 移動檔案指針 ( 起始位置預設 0 表示檔案開頭,1 為當前位置,2 為檔案結尾 )。
close() 關閉檔案,並釋出記憶體。
  • read(size)

    範例的程式碼使用兩種方式讀取內容為 hello world 的 txt 檔案 ( 如果只設定一個 f1,使用 read() 之後就會讀取整份檔案,read(2) 就會失效,所以使用 f1 和 f2 ),如果沒有設定 size,則完整讀取整份檔案,如果有設定 size,則讀取到 size 的字元數,讀取的檔案如果超過電腦的記憶體大小,則會發生問題 ( 讀取 1GB 的檔案就會消耗 1GB 的記憶體 )

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    f2 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    a = f1.read()
    b = f2.read(2)
    print(a)     # hello world
    print(b)     # he ( 只讀取前兩個字元 )
    f1.close()
    f2.close()
    
  • readline(size)

    範例的程式碼使用兩種方式讀取內容為第一行 hello world 的 txt 檔案,如果沒有設定 size,則完整讀取第一行,如果有設定 size 則讀取第一行的 size 字元數,若 size 超過第一行的數量,就會完整讀取第一行 ( 就算檔案有很多行,還是只會讀取第一行 )。

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    f2 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    a = f1.readline()
    b = f2.readline(2)
    print(a)      # hello world
    print(b)      # he ( 只讀取單一行的前兩個字元 )
    f1.close()
    f2.close()
    
  • readlines(size)

    範例的程式碼使用兩種方式讀取內容為三行 hello world、good morning 和 12345 的 txt 檔案,如果沒有設定 size 則讀取全部的檔案內容,以行為單位回傳為串列,如果有設定 size,則會以 size 抵達的字元位置行數為最大行數,回傳為串列

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    f2 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    a = f1.readlines()      # 讀取全部的行,變成串列形式
    b = f2.readlines(20)    # 讀取包含 20 個字元的行,變成串列形式
    print(a)      # ['hello world\n', 'good morning\n', '12345']
    print(b)      # ['hello world\n', 'good morning\n']
    f1.close()
    f2.close()
    
  • readable()

    範例的程式碼執行後,會顯示這個檔案是否能讀取,或是否能寫入,回傳 True 或 False。

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','w')
    f2 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    print(f1.readable())    # Fasle  因為設定 w
    print(f2.readable())    # True   因為設定 r
    f1.close()
    f2.close()
    
  • f.write(文字內容)

    範例的程式碼執行後,會清空原本 test.txt 的內容,寫入新的內容

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','w')
    f1.write('good morning')     # 寫入 good morning
    f1.close()
    
  • f.writelines(文字內容串列)

    範例的程式碼執行後,會清空原本 test.txt 的內容,並以串列方式寫入內容,如果需要換行必須自行加入換行符號 \n。

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','w')
    f1.writelines(['123\n','456\n','789\n'])   # 寫入三行內容
    f1.close()
    
  • writeable()

    範例的程式碼執行後,會顯示這個檔案是否能讀取,或是否能寫入,回傳 True 或 False。

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','w')
    f2 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    print(f1.writeable())    # True   因為設定 w
    print(f2.writeable())    # False  因為設定 r
    f1.close()
    f2.close()
    
  • tell()

    範例的程式碼執行後,會回傳目前讀取檔案指針的位置 ( 檔案從頭算起的字元數 )。

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')
    a = f1.read(5)    # 讀取前五個字元,讀去完畢後指針位在 5
    t = f1.tell()     # 讀取指針位置
    print(a)          # hello
    print(t)          # 5
    f1.close()
    
  • seek(偏移量, 起始位置)

    範例的程式碼執行後,會將指針從開頭位置移動 5 個字元,然後再讀取 5 個字元 ( 起始位置預設 0 表示檔案開頭,1 為當前位置,2 為檔案結尾 )。

    f1 = open('/content/drive/MyDrive/Colab Notebooks/test.txt','r')   # 內容為 123456789
    f1.seek(2,0)     # 將指針移動到 2 和 3 中間
    a = f1.read(5)   # 讀取後方五個字元
    print(a)         # 34567
    f1.close()
    
  • close()

    關閉檔案,並釋出記憶體。

使用 with

使用 with 可以讓開啟檔案,執行相關內容後自動關閉並釋出記憶體,使用的語法如下:

with open('demo/test.txt','w') as f1:
    f1.write('good morning')     # 寫入 good morning
    # 完成後如果沒有後續動作,就會自動關閉檔案

更多教學

大家好,我是 OXXO,是個即將邁入中年的斜槓青年,我有個超過一千篇教學的 STEAM 教育學習網,有興趣可以參考下方連結呦~ ^_^


上一篇
( Day 13.2 ) Python 繼承 inheritance
下一篇
( Day 14.2 ) Python 匯入模組 import
系列文
跟著 OXXO 一起學 Python101
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言