存檔要儲存什麼呢?直覺告訴我們應該要儲存 Encrypt 物件 (object) ,不過可以簡單點,儲存密碼表就可以了
↓
code.txt
完整程式請參考「範例程式碼」的 encrypt.py 、 encrypt_view.py 及 encrypt_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 中顯示猜測記錄。 |
相關教學影片