Python 入門指南 V2.00 - 單元 25 - 存檔與載入




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



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

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


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

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


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


sm() 方法的實作如下


090# 按下 Save 按鈕的事件 
091def sm(self):
092   # 先測試是否有按過 New 按鈕
093   if self.e == None:
094      m = "It can not save!!"
095      self.dt["text"] = m
096   else:
097      # 有按過 New 按鈕就進行存檔工作
098      f = open('./code.txt''w')
099      f.write("".join(self.e.code))
100      f.closed
101      self.dt["text"] = "It's Done."

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


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

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


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

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


100f.closed
101self.dt["text"] = "It's Done."

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


075# 按下 Load 按鈕的事件 
076def lm(self):
077   # 先測試檔案是否存在
078   if os.path.exists("./code.txt"):
079      # 檔案存在就進行載入工作
080      f = open('./code.txt''r')
081      code = f.readline()
082         self.e = Encrypt(code)
083         s = str("".join(self.e.code))
084         m = "code: " + s
085      self.dt["text"] = m
086   else:
087      m = "Load denied!!"
088      self.dt["text"] = m

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


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

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


004import os

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


081code = f.readline()

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


078self.e = Encrypt(code)

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



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



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



下面是載入



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


中英文術語對照


物件object
序列化serialization
字串string
類別class
屬性attribute
方法method
參數parameter

重點整理


  1. 存檔可儲存物件或字串,儲存物件須使用標準模組庫中的 pickle ,儲存字串可將字串直接寫入純文字檔案中。
  2. 檔案處理利用內建函數 open() ,取得檔案物件後利用 write() 方法寫入資料,而 readline() 可讀取資料,結束檔案處理工作後利用 closed 關閉檔案物件。
  3. os.path.exists() 可判斷指定路徑的檔案是否存在。
  4. GUI 中任何一個動作都應該要顯示提示訊息給使用者,好讓使用者知道操作是否成功。


問題與討論


  1. 為什麼儲存物件還要序列化,字串也是物件,可是字串卻不用?
  2. 載入前如果檔案不存在會發生什麼情況?有其他的解決方式嗎?

練習


  1. 承接上一個單元的 guessgame_gui.py ,繼續實作 Guess 按鈕,將所有提示訊息都顯示在下方的 Label 上。
  2. 承上題,想一想猜數字遊戲要不要有存檔的機制。

the end

沒有留言: