Python 入門指南

單元 26 - 存檔與載入

~~學習進度表~~

存檔要儲存什麼呢?直覺告訴我們應該要儲存 Encrypt 物件 (object) ,不過可以簡單點,儲存密碼表就可以了

Encrypt → code
        ↓
         code.txt

完整程式請參考「範例程式碼」的 encrypt.pyencrypt_view.pyencrypt_controller.py

要直接儲存整個 Encrypt 物件到檔案也不是不可以,只是這麼一來就牽涉到物件還要序列化 (serialization) ,反倒因為密碼表是字串 (string) ,因此可以字串的方式來存檔。

儲存物件要利用標準程式庫 (standard library) 中的 pickle 模組 (module)

這是個相對簡單的方式,也就是說, Encrypt 類別 (class)code 屬性 (attribute) 為密碼表字串,然後把這個字串儲存到一個固定檔名的純文字檔裡,就完成存檔的工作了。載入就讀取這個純文字檔,取得密碼表字串再重新建立 e ,並以密碼表字串__init__() 方法 (method) 的參數即可。

概念很簡單,可是跑程式時可能也會發生某些問題,例如 e 的初值為 None 的情況,如果使用者沒有按過新建就按下儲存,程式就會發生錯誤,因此這邊也要先進行條件檢查。

sm() 方法的實作如下

# 按下儲存按鈕的事件
def sm(self):
  # 先測試是否有按過新建按鈕
  if self.e == None:
    m = "無法儲存!"
    self.app.dt["text"] = m
  else:
    # 有按過新建按鈕就進行存檔工作
    f = open('./code.txt', 'w')
    f.write("".join(self.e.code))
    f.closed
    self.app.dt["text"] = "完成存檔!"

這裡利用內建函數 open() 打開並且建立檔案,需要兩個參數 (parameter) ,第一個參數為檔案路徑名稱,第二個參數則是檔案處理模式,這裡 'w' 表示寫入,若 code.txt 不存在就會建立檔案

f = open('./code.txt', 'w')

f 取得檔案物件,接著寫入內容到檔案是利用檔案物件write() 方法,參數就是要寫入的字串內容

f.write("".join(self.e.code))

存檔工作結束,先呼叫 closed 方法關閉檔案物件,最後在訊息欄顯示檔案儲存成功訊息

f.closed
self.app.dt["text"] = "完成存檔!"

載入則是讀取 code.txt 中的內容,因為檔案內容就是密碼表。不過載入時有可能發生檔案不存在的情況,就是使用者沒有按過儲存按鈕囉!這樣的話,相同目錄下不會存在 code.txt 檔案,所以這邊也是先做個檔案是否存在的條件檢查,程式如下

# 按下載入按鈕的事件
def lm(self):
  # 先測試檔案是否存在
  if os.path.exists("./code.txt"):
    # 檔案存在就進行載入工作
    f = open('./code.txt', 'r')
    code = f.readline()
    self.e = Encrypt(code)
    s = str("".join(self.e.code))
    m = "密碼表: " + s
    self.app.dt["text"] = m
  else:
    m = "無法載入!"
    self.app.dt["text"] = m

這裡我們先用 os.path.exists() 判斷檔案是否存在

# 先測試檔案是否存在
if os.path.exists("./code.txt"):

因為用了標準程式庫裡的 os 模組,所以前面要先 import os

import os

若不存在訊息欄就顯示載入失敗的訊息,若存在就進行載入工作,這裡是用檔案物件readline() 方法

code = f.readline()

然後我們將 code 設定給 e 即可,這裡同樣 e 直接建立一個帶有參數Encrypt 物件

self.e = Encrypt(code)

來執行看看囉!下面是存檔

相同目錄下就會新增 code.txt

開啟 code.txt 檢查密碼表是否有存入

下面是載入

功能 OK ,接下來就剩兩個方法要完成實作囉!

中英文術語對照
物件object
序列化serialization
字串string
標準程式庫standard library
模組module
類別class
屬性attribute
方法method
參數parameter
重點整理
1. 存檔可儲存物件或字串,儲存物件須使用標準程式庫中的 pickle ,儲存字串可將字串直接寫入純文字檔案中。
2. 檔案處理利用內建函數 open() ,取得檔案物件後利用 write() 方法寫入資料,而 readline() 可讀取資料,結束檔案處理工作後利用 closed 關閉檔案物件。
3. os.path.exists() 可判斷指定路徑的檔案是否存在。
4. GUI 中任何一個動作都應該要顯示提示訊息給使用者,好讓使用者知道操作是否成功。
問題與討論
1. 為什麼儲存物件還要序列化,字串也是物件,可是字串卻不用?
2. 載入前如果檔案不存在會發生什麼情況?有其他的解決方式嗎?
練習
1. 承接上一個單元的 hello_controller.py ,想一想可以替 HelloController 擴充什麼功能,像是可以清除原本輸入內容,然後讓使用者重新輸入。
2. 承接上一個單元的 game_controller.py ,相同資料夾中加入單元 21 完成的 guessgame.py ,替 GameView 加入一個視窗元件 Text ,然後在 Text 中顯示猜測記錄。

相關教學影片

上一頁 單元 25 - 整合 Encrypt 類別
回 Python 入門指南首頁
下一頁 單元 27 - 完成版的 EncryptController
回 Python 教材首頁
回程式語言教材首頁