第一個 Python Class

不該過度設計, 而是在後續重構過程逐漸把設計加進來

非正規程式設計訓練出身的深度學習工程師, 通常相當熟悉運用 Jupyter 完成資料處理, 模型訓練, 以及後續的預測, 甚至製作非常專業的圖表分析, 不需太費力進行設計, 邊做邊完成腳本的開發, 很有機會把工作順利結束. Python + Jupyter 強大且易用, 很容易讓工程師忘記它可是一個完整語言, 求快的心態, 犧牲了程式的可讀性, 或是增大後續維護困難. 為了讓程式具備維護性, 後續嘗試以一般物件導向程式開發的方式來進行.

針對一個工作目錄, 命名為 WorkFolder, 下存放一堆照片等待標示的照片, 我們必須擴充讓它滿足下面的需求:

  1. 當下畫面呈現的圖片被標示為 X類別時, 應自動搬移到子目錄X下

  2. 完成標示一張圖後, 立即跳下一張圖片並自動呈現

  3. 可放心按快速鍵就可進行標示, 因為系統提供反悔可回復上(或是上上...個)誤標示的圖片

很明顯 pathlib 提供的 Path Class 還未能完整滿足上述需求, 需要擴充 - 用WorkFolder(Path)代表.

先把整個 Class程式呈現出來:

為了讓程式可設定有哪些分類, 我們需要在此程式同一目錄下有 config. ini 檔案, 然後用 config.read('config.ini',encoding='utf-8') 來讀取其內容. config.ini 裡邊至少要包含類似如下的段落.

[class] 這一行呼應 config.items('class') 下放置了 分類代碼與對應名稱.

[class]

3 = 圖像不足以進行檢測

2 = 瑕疵品

1 = 待進一步檢測

0 = 良品

我們用字串 '3' 來代表 <圖像不足以進行檢測> 此分類; 同理, '2' 代表 <瑕疵品>; '1' 代表 <待進一步檢測>. 其中 '3'/'2'/'1'/'0' 是未來標示後資料集用的代碼, 簡潔一點即可; 而諸如<'圖像不足以進行檢測'/.../'良品'> 是用戶可以看到分類名稱, 所以必須貼近其術語.

用戶可以依照其需求編寫其分類. 這個必須再進行標示之前, 用戶與數據或是深度學習專家充分溝通過後, 決定出來的. 因為設計的不好, 有可能造成重工, 必須謹慎, 有些細節以後找機會來探討.

接著我們設計一個繼承Path 的WorkFolder Class, 而且我們希望它可以在 Windows, Mac, 甚或 Linux 都可以順利執行, 所以加上這一行:

_flavour = _windows_flavour if os.name == 'nt' else _posix_flavour

最主要的兩個實例方法 self.labelCurrentImg 與 self.rollback. 我們用 self.remains 與 self.history 兩個實例變數來記錄還有哪些圖片等著被標示, 以及已經完成標示的歷史紀錄. 而 self.current 紀錄在當下畫面呈現出來要被標示的圖片.