不間斷 Python 挑戰 Day 27 - 檔案、資料夾與路徑

更新於 2022/11/10閱讀時間約 13 分鐘
到目前為止,我們都還是在附檔名為.py的Python檔案執行程式碼,當程式需要與外部的檔案互動,例如讀取文字、表格、或是影像來做分析,或是把程式執行的結果儲存下來,就需要能夠存取外部的檔案。例如,在上一節中,當貪食蛇遊戲結束之後,隨著程式停止執行,該次的分數也就被丟棄,若能將分數記錄下來,下次遊戲開始時便能在螢幕上顯示當前的最高分數,也更接近真實的遊戲情境。

檔案

接著一一說明檔案的開啟、讀取、以及寫入的方法。

開啟檔案

為方便範例的展示,我們在主程式所在的目錄建立一個readme.txt,裡面先打上一些文字。
專案資料夾
readme.txt內容
檔案使用open()函數開啟,語法如下:
open(file, mode='r', encoding=None)
  • file:檔案路徑
  • mode:打開文件的模式,預設為'r',意即僅供讀取。可用的模式有:
  - 'r':讀取(預設值)
  - 'w':寫入,已存在的文件會被清除
  - 'x':排他性創建,若文件已存在則失敗
  - 'a':打開文件用於寫入,若文件已存在則在尾端寫入
  - 'b':二進制模式
  - 't':文字模式(預設值)
  - '+':打開進行更新,可讀可寫
  • encoding:用於解碼或編碼文件的格式
檔案使用open()函數所開啟後,存入file物件。
# 讀取檔案
file = open("readme.txt", mode='r', encoding="utf-8")

讀取檔案

檔案開啟後,可使用read()函數讀取該檔案,存成一個字串,之後便可使用print()函數將檔案內容印出。
data = file.read()
print(data)
file.close()
執行結果:
這是python說明檔。
今天將介紹檔案的讀寫、資料夾與路徑。
持續學習!

開啟檔案的另一種方式:with關鍵字

當使用open()函數開啟檔案時,必須在檔案使用完畢後,用close()函數關閉檔案,否則在程式執行的過程中,該檔案會一直被占用,可能造成不可預期的錯誤。好消息是,Python也提供了使用with關鍵字來開啟檔案的方式,在with關鍵字的區塊結束之後自動關閉檔案,來避免因疏忽而沒有讓close()和open()成對出現的錯誤。
with關鍵字的使用方法如下:
with open(檔案) as 檔案物件:
  對檔案的操作
因此,前面的範例可以這樣改寫:
# 使用with讀取檔案
with open("readme.txt", mode='r', encoding="utf-8") as file:
  data = file.read()
  print(data)
也會得到一樣的執行結果:
這是python說明檔。
今天將介紹檔案的讀寫、資料夾與路徑。
持續學習!

逐行讀取

若想要逐行讀取檔案的內容,可以搭配for迴圈來使用。
# 逐行讀取
with open("readme.txt", mode='r', encoding="utf-8") as file:
  for line in file:
    print(line)
執行結果:
這是python說明檔。
今天將介紹檔案的讀寫、資料夾與路徑。
持續學習!
另外,也可以使用readlines()函數,差別在於此函數會將每一行的內容做為串列的元素存入串列。
# 逐行讀取
with open("readme.txt", mode='r', encoding="utf-8") as file:
  data_list = file.readlines()
  print(data_list)
注意到輸出的結果變成串列,其中也包括了換行字元。
['這是python說明檔。\n', '今天將介紹檔案的讀寫、資料夾與路徑。\n', '持續學習!']
若要去除行末的換行符號,可使用rstrip()函數達成。
for line in data_list:
  print(line.rstrip())
執行結果:
這是python說明檔。
今天將介紹檔案的讀寫、資料夾與路徑。
持續學習!

寫入檔案

當程式執行過程有數據要保存下來時,就要透過寫入檔案的方式來將結果存入檔案內,使用的函數是write()。要注意的是,此時open()函數的開啟模式必須為可以寫入的模式,例如mode='w',程式會自動建立要寫入的檔案,若該檔案原本已存在,則檔案的內容會被清空。
以下範例建立一個檔案來寫入文字,可看到執行後,專案資料夾中就多了一個record.txt檔案,開啟該檔案即可看到程式所寫的內容。
# 寫入檔案
with open("record.txt", mode='w', encoding="utf-8") as file:
  file.write("檔案寫入範例\n")
專案資較夾
寫入到record.txt

附加檔案

寫入的內容也可以附加到檔案的末端,此時open()函數的開啟模式必須為mode='a',若開啟的檔案不存在,程式會自動建立要寫入的檔案,若該檔案原本已存在,寫入的內容會附加到檔案的末端。
# 附加檔案
with open("record.txt", mode='a', encoding="utf-8") as file:
  file.write("附加檔案範例\n")

資料夾與路徑

絕對路徑

路徑從根目錄開始,例如今天的範例,main.py在我的電腦的絕對路徑為:/User/wjweng/PyCharmProjects/marathon_python/Day27/main.py
專案資料夾

相對路徑

在main.py的主程式裡,若要使用到其它檔案的內容,除了絕對路徑以外,也可用相對路徑來表達,所謂相對亦即相對於main.py所在的工作目錄的位置,例如main.py的相對路徑即為main.py或./main.py,"."指的是當前的資料夾,在使用上"./"可以省略。
當我們把上一節的貪食蛇遊戲程式加入本節的專案後,若我們要找scoreboard.py,它的相對路徑會變成./snake/scoreboard.py或snake/scoreboard.py。
專案資料夾加入貪食蛇遊戲

取得工作目錄

Python的os模組為處理作業系統相關及目錄路徑的模組,使用os模組的getcwd()方法可以取得當前的工作目錄。
# 取得目前的工作目錄
import os
print(os.getcwd())
執行結果:
C:\Users\wjweng\PycharmProjects\marathon_python\Day27

取得絕對路徑

使用os.path模組的abspath(path)方法可傳回path的絕對路徑。
# 取得絕對路徑
print(os.path.abspath("main.py"))
執行結果:
C:\Users\wjweng\PycharmProjects\marathon_python\Day27\main.py

取得相對路徑

使用os.path模組的relpath(path[, start])方法可傳回path相對於start的路徑,若省略start,則回傳相對於工作目錄的路徑。
# 取得相對路徑
print(os.path.relpath("c:\\"))
執行後所顯示的".."代表上一層資料夾,這裡代表我的c槽位置為工作目錄的上五層。
..\..\..\..\..

檢查路徑

使用os.path模組的exists(path)方法可檢驗path的檔案或資料夾是否存在,若存在則回傳True,反之則為False。
# 檢查路徑
print(os.path.exists("snake/scoreboard.py"))
print(os.path.exists("snake/highest_score.txt"))
從前面專案資料夾的內容可知,snake資料夾內有scoreboard.py,但沒有highest_score.txt,所以分別回傳True跟False。
True
False

貪食蛇最高分記錄補完

有了以上的預備知識後,就可以來為上一節的貪食蛇遊戲加上記錄最高分的功能,新增的部分用粗體字顯示。我們在snake資料夾新增一個highest_score.txt檔案,在每次遊戲結束後用於記錄最高分數,若該次遊戲有破紀錄就更新檔案。在初始化函數中,先檢查highest_score.txt檔案是否存在,如果存在,則將分數顯示在畫布上,反之則將最高分初始化為0。在game_over()方法裡面,判斷該次遊戲的分數是否超過最高分,若是,則將分數寫入highest_score.txt裡面。
# scorebaord.py
class Scoreboard(Turtle):
  def __init__(self):
    super().__init__()
    self.score = 0
    self.hideturtle()
    self.penup()
    self.color(SCORE_COLOR)
    self.speed("fastest")
    self.goto(SCORE_POSITION)
    if path.exists("snake/highest_score.txt"):
      with open("snake/highest_score.txt", mode='r') as score_file:
        self.highest_score = int(score_file.read())
    else:
      self.highest_score = 0
    self.write(f"score: {self.score}, highest_score: {self.highest_score}", False, align="center", font=("Arial", 20, "normal"))
  def get_score(self):
    self.score += 1
    self.clear()
    self.write(f"score: {self.score}, highest_score: {self.highest_score}", False, align="center", font=("Arial", 20, "normal"))
 
  def game_over(self):
    self.color(GAMEOVER_COLOR)
    self.goto(GAMEOVER_POSITION)
    self.write("Game Over", False, align="center", font=("Arial", 40, "normal"))
 
    if self.score > self.highest_score:
      with open("snake/highest_score.txt", mode='w') as score_file:
        score_file.write(str(self.score))
在第一次遊戲結束後,可看到snake資料夾裡面多了一個highest_score.txt,裡面記錄我第一次遊戲的分數。
第一次遊戲結束
第二次進行遊戲即可在上方highest_score的位置看到上一次遊戲(也就是目前的最高分)的分數了。
第二次遊戲

程式範例

avatar-img
47會員
36內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Wei-Jie Weng的沙龍 的其他內容
接續前一篇文章,說明貪食蛇遊戲架構的後半部份,來完成整個遊戲的程式設計。
接下來我們會運用之前所學過的各種觀念,包括Turtle 模組、繼承等等,來製作這個大家都熟知的小遊戲-貪食蛇。完成品會長得像下圖這樣,包括可以設定難度(速度)、使用鍵盤的上、下、左、右鍵來移動貪食蛇的移動方向來吃到食物並加長蛇身、以及記分板等。
Turtle Graphic的前身是一種設計給小朋友學習的簡易繪圖程式,最初來自於Wally Feurzeig、Seymour Papert和Cynthia Solomon於1967年所創造的Logo編程語言,它是Python內建的繪圖函式庫,我們可以根據函式庫裡面的指令,操控一隻或多隻「小烏龜」在
「繼承」顧名思義就是有一個或多個類別延續了某個類別的特性,就如同在人類社會裡,兒女接收了父母的財產、承襲了上代的技能、延續了前一輩的事業。在Python的語言裡,能夠繼承的特性為類別的屬性與方法,繼承的類別稱為子類別(child class / subclass)或衍伸類別(derived clas
在類別一節中,我們可以用Student類別的實體來存取類別中的name變數、score字典、以及其中的所有方法,這些可以被類別以外的程式碼所直接存取的屬性稱為公有屬性(public attribute)、可以被類別以外的程式碼所直接呼叫的方法稱為公有方法(public method)。
大型程式的開發通常不會由一個人獨力完成,而是將程式依功能拆分成不同的函數或是類別,由不同人協力開發成各個模組,最後再將這些模組導入主程式,或是直接套用現有的模組。模組依來源可以分成三大類: Python內建的模組 外部模組,需從第三方的軟體儲存庫(如PyPI)並安裝使用 程式開發者自行開發的模組
接續前一篇文章,說明貪食蛇遊戲架構的後半部份,來完成整個遊戲的程式設計。
接下來我們會運用之前所學過的各種觀念,包括Turtle 模組、繼承等等,來製作這個大家都熟知的小遊戲-貪食蛇。完成品會長得像下圖這樣,包括可以設定難度(速度)、使用鍵盤的上、下、左、右鍵來移動貪食蛇的移動方向來吃到食物並加長蛇身、以及記分板等。
Turtle Graphic的前身是一種設計給小朋友學習的簡易繪圖程式,最初來自於Wally Feurzeig、Seymour Papert和Cynthia Solomon於1967年所創造的Logo編程語言,它是Python內建的繪圖函式庫,我們可以根據函式庫裡面的指令,操控一隻或多隻「小烏龜」在
「繼承」顧名思義就是有一個或多個類別延續了某個類別的特性,就如同在人類社會裡,兒女接收了父母的財產、承襲了上代的技能、延續了前一輩的事業。在Python的語言裡,能夠繼承的特性為類別的屬性與方法,繼承的類別稱為子類別(child class / subclass)或衍伸類別(derived clas
在類別一節中,我們可以用Student類別的實體來存取類別中的name變數、score字典、以及其中的所有方法,這些可以被類別以外的程式碼所直接存取的屬性稱為公有屬性(public attribute)、可以被類別以外的程式碼所直接呼叫的方法稱為公有方法(public method)。
大型程式的開發通常不會由一個人獨力完成,而是將程式依功能拆分成不同的函數或是類別,由不同人協力開發成各個模組,最後再將這些模組導入主程式,或是直接套用現有的模組。模組依來源可以分成三大類: Python內建的模組 外部模組,需從第三方的軟體儲存庫(如PyPI)並安裝使用 程式開發者自行開發的模組
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!