
互動式環境可以直接測試程式碼,如果有錯或無法執行的地方,也會直接停下來告訴我們,例如
| >>> def do_something(a, b): |
| ... return a + b |
| ... |
| >>> do_something(3, "3") |
| Traceback (most recent call last): |
| File "<stdin>", line 1, in <module> |
| File "<stdin>", line 2, in do_something |
| TypeError: unsupported operand type(s) for +: 'int' and 'str' |
| >>> |
當然這是個故意的錯誤,倒是簡單的示範簡單的函數 (function) 或類別 (class) 都可以直接放到互動式介面中測試,這就是互動式介面方便的地方。
互動式介面還有一個很大的優點,就是可以直接拿標準模組庫 (standard library) 的內容來測試或學習。例如以下 import 標準模組庫的 math 模組 (module)
| >>> import math |
| >>> math.ceil(55.9801) |
| 56 |
| >>> math.factorial(12) |
| 479001600 |
| >>> math.log2(1024) |
| 10.0 |
| >>> |
不過這可能僅限於小程式或測試相關程式碼的部分,就單一類別或函數或模組。當有需要組合多個函數或類別之時,最好把程式碼放到模組中,也就是副檔名為 .py 的檔案內。例如以下猜數字遊戲要猜 0 到 9 十個數字之一
| 001 | import random |
| 002 | |
| 003 | answer = random.randint(0, 9) |
| 004 | while True: |
| 005 | guess = input(":") |
| 006 | if guess == answer: |
| 007 | print("Right!!") |
| 008 | break |
| 009 | else: |
| 010 | print("Wrong!!") |
假設程式碼在文字編輯器 (text editor) 中打好,我們就可以在命令列裡打指令執行,執行結果如下
| $ python3 guessgame.py |
| :1 |
| Wrong!! |
| :2 |
| Wrong!! |
| :3 |
| Wrong!! |
| :4 |
| Wrong!! |
| :5 |
| Wrong!! |
| :6 |
| Wrong!! |
| :7 |
| Wrong!! |
| :8 |
| Wrong!! |
| :9 |
| Wrong!! |
| :0 |
| Wrong!! |
| : |
0 到 9 每個數字都猜了,沒有一個數字是對的,因為程式中有個錯誤。我們暫時跳過不談這個錯誤,先切換到 IDE 中測試,以下為 PyCharm 的社群版

執行後,依序輸入 0 到 9 每個數字,結果一樣,我們點擊右上角蟲的圖示,開啟除錯模式看看

PyCharm 整合 pydev 這款式覺化的除錯器 (debugger)

重新執行以後結果一樣

PyCharm 也有些建議修改的選項,燈號出現就可以查看

錯誤共有三種,第一種是語法錯誤 (syntax errot) , IDE 或直譯器 (interpreter) 會直接挑出來,第二種是執行期間錯誤 (run-time error) ,這一類的錯誤也是由直譯器執行時挑出,或是藉由除錯工具或有除錯工具的 IDE 來分析,第三種也是最麻煩的一種叫做語意錯誤 (semantic error) ,如同這個猜數字程式,程式可以順利執行,卻得不到預期結果。
錯誤其實發生在第 6 行,迴圈 (loop) 的結束條件設定為如果 guess 等於 answer ,就印出 "Right!!" 然後跳出迴圈,隨之結束程式
| 006 | if guess == answer: |
問題是 guess 永遠不會等於 answer ,原因很簡單,因為 answer 是整數型態,而 guess 利用 input() 從命令列擷取輸入,所以 guess 得到的是字串 (string) 而非整數 (integer) ,這裡拿字串跟整數做比較,自然永遠不會相等。
要讓迴圈順利結束有兩種方式,一種是把 answer 轉換為字串,或是把 guess 轉換為整數,這裡採用後者,第 6 行修改如下
| 006 | if int(guess) == answer: |
重新執行就可順利結束

我們把猜數字遊戲的程式碼放在 guessgame.py 的檔案內,要知道一個 Python 程式就是一個模組,模組執行時所有未縮排的程式碼都會優先執行,所以如果這樣做
| import guessgame |
引入的程式就會先執行猜數字遊戲一次,如果要避免被 import 後去執行未縮排的程式碼,此時可以把該為縮排的程式碼放在
| if __name__ == "__main__": |
之後,這樣做為測試沒有縮排的程式碼就不會被執行了。
以上我們用很簡單只有幾行的猜數字遊戲示範測試、除錯等工作,開發大型程式時卻可能多達數百萬行程式碼,這時候需要把程式拆成許多的小單元分別進行測試,每個小單元都正確無誤後,再組合成完整的程式。
當模組越多,再來就是用資料夾(目錄)整理相關的模組,一個資料夾(目錄)中加入 __init__.py 就構成一個套件 (package) ,模組庫也就是用套件的方式來組織的。
the end
Python 新手之旅 V1.10 (Google Play)
沒有留言:
張貼留言