存檔要儲存什麼呢?直覺告訴我們應該要儲存 Encrypt 物件 (object) ,不過可以簡單點,儲存密碼表就可以了
完整程式請參考「範例程式碼」的 encrypt.py 及 encrypt_gui.py 。
要直接儲存整個 Encrypt 物件到檔案也不是不可以,只是這麼一來就牽涉到物件還要序列化 (serialization) ,反倒因為密碼表是字串 (string) ,因此可以字串的方式來存檔。
儲存物件要利用標準模組庫 (standard library) 中的 pickle 模組 (module) 。
這是個相對簡單的方式,也就是說, Encrypt 類別 (class) 的 code 屬性 (attribute) 為密碼表字串,然後把這個字串儲存到一個固定檔名的純文字檔裡,就完成存檔的工作了。載入就讀取這個純文字檔,取得密碼表字串再重新建立 e ,並以密碼表字串當 __init__() 方法 (method) 的參數即可。
概念很簡單,可是跑程式時可能也會發生某些問題,例如 self.e 的初值為 None 的情況,如果使用者沒有按過 New 就按下 Save ,程式就會發生錯誤,因此這邊也要先進行條件檢查。
sm() 方法的實作如下
090 | # 按下 Save 按鈕的事件 |
091 | def 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 不存在就會建立檔案
098 | f = open('./code.txt', 'w') |
f 取得檔案物件,接著寫入內容到檔案是利用檔案物件的 write() 方法,參數就是要寫入的字串內容
099 | f.write("".join(self.e.code)) |
存檔工作結束,先呼叫 closed 方法關閉檔案物件,最後在訊息欄顯示檔案儲存成功訊息
100 | f.closed |
101 | self.dt["text"] = "It's Done." |
載入則是讀取 code.txt 中的內容,因為檔案內容就是密碼表。不過載入時有可能發生檔案不存在的情況,就是使用者沒有按過 Save 按鈕囉!這樣的話,相同目錄下不會存在 code.txt 檔案,所以這邊也是先做個檔案是否存在的條件檢查,程式如下
075 | # 按下 Load 按鈕的事件 |
076 | def 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 | # 先測試檔案是否存在 |
078 | if os.path.exists("./code.txt"): |
因為用了標準模組庫理的 os 模組,所以前面要先 import os
004 | import os |
若不存在訊息欄就顯示載入失敗的訊息,若存在就進行載入工作,這裡是用檔案物件的 readline() 方法
081 | code = f.readline() |
然後我們將 code 設定給 self.e 即可,這裡同樣 self.e 直接建立一個帶有參數的 Encrypt 物件
078 | self.e = Encrypt(code) |
來執行看看囉!下面是存檔
相同目錄下就會新增 code.txt
開啟 code.txt 檢查密碼表是否有存入
下面是載入
功能 ok ,接下來就剩兩個方法要完成實作囉!
中英文術語對照
物件 | object |
序列化 | serialization |
字串 | string |
類別 | class |
屬性 | attribute |
方法 | method |
參數 | parameter |
重點整理
- 存檔可儲存物件或字串,儲存物件須使用標準模組庫中的 pickle ,儲存字串可將字串直接寫入純文字檔案中。
- 檔案處理利用內建函數 open() ,取得檔案物件後利用 write() 方法寫入資料,而 readline() 可讀取資料,結束檔案處理工作後利用 closed 關閉檔案物件。
- os.path.exists() 可判斷指定路徑的檔案是否存在。
- GUI 中任何一個動作都應該要顯示提示訊息給使用者,好讓使用者知道操作是否成功。
問題與討論
- 為什麼儲存物件還要序列化,字串也是物件,可是字串卻不用?
- 載入前如果檔案不存在會發生什麼情況?有其他的解決方式嗎?
練習
- 承接上一個單元的 guessgame_gui.py ,繼續實作 Guess 按鈕,將所有提示訊息都顯示在下方的 Label 上。
- 承上題,想一想猜數字遊戲要不要有存檔的機制。
the end
沒有留言:
張貼留言