調試和編寫程序方法

當出現語法錯誤或者運行錯誤時

錯誤信息會很多,但是通常有用部分是:

  • 是哪類錯誤
  • 在哪兒出現
是應該花一些時間仔細閱讀錯誤信息,但是不要輕易的認爲錯誤信息的提示都是準確的,特別是錯誤信息的位置,有時候並不是真正的繁盛錯誤的地方。

增量式開發(incremental)

增量式開發的目標,是通過每次只增加和測試少量代碼,來避免長時間的調試。
先建立骨架,具體代碼可以不放,然後慢慢增加。

這種開發方式的關鍵是:

  1. 從一個能運行的程序開始,並且每次只增加少量改動。無論你何時遇到錯誤,都能夠清楚定位錯誤的源頭。
  2. 用臨時變量存儲中間值,這樣你就能顯示並檢查它們。
  3. 一旦程序正確運行,你要刪除一些腳手架代碼,或者將多條語句組成複合表達式,但是前提是不會影響程序的可讀性。

粗心的使用列表

  • 大多數的列表方法會對參數進行修改,然後返回 None 。這和字符串方法相反,後者保留原始的字符串並返回一個新的字符串。

如果你習慣這樣寫字符串代碼:

word = word.strip()

那麼你很可能會寫出下面的列表代碼:

t = t.sort()           # 錯誤!

因爲 sort 返回 None ,所以你的下一個對 t 執行的操作很可能會失敗。


  • 選擇一種寫法,堅持下去。

列表的一個問題就是有太多方法可以做同樣的事情。 例如,要刪除列表中的一個元素,你可以使用 pop 、remove 、del 甚至是切片賦值。

要添加一個元素,你可以使用 append 方法或者 + 運算符。假設 t 是一個列表,x 是一個列表元素,以下這些寫法都是正確的:

t.append(x)
t = t + [x]
t += [x]

而這些是錯誤的:

t.append([x])          # 錯誤!
t = t.append(x)        # 錯誤!
t + [x]                # 錯誤!
t = t + x              # 錯誤!

  • 通過創建拷貝來避免別名.

如果你要使用類似 sort 這樣的方法來修改參數, 但同時有要保留原列表,你可以創建一個拷貝。

>>> t = [3, 1, 2]
>>> t2 = t[:]
>>> t2.sort()
>>> t
[3, 1, 2]
>>> t2
[1, 2, 3]

在這個例子中,你還可以使用內置函數 sorted ,它將返回一個新的已排序的列表,原列表將保持不變。

>>> t2 = sorted(t)
>>> t
[3, 1, 2]
>>> t2
[1, 2, 3]

操作大的數據集時


  • 縮小輸入:

如果可能,減小數據集合的大小。 例如,如果程序讀入一個文本文件,從前10行開始分析,或是找到更小的樣例。 你可以選擇編輯讀入的文件,或是(最好)修改程序使它只讀入前 n 行。

如果出錯了,你可以將 n 縮小爲會導致該錯誤的最小值,然後在查找和解決錯誤的同時,逐步增加 n 的值。

  • 檢查摘要和類型

考慮打印數據的摘要,而不是打印並檢查全部數據集合: 例如,字典中項的數目或者數字列表的總和。

運行時錯誤的一個常見原因,是值的類型不正確。 爲了調試此類錯誤,打印值的類型通常就足夠了。

  • 編寫自檢代碼

有時你可以寫代碼來自動檢查錯誤。 例如,如果你正在計算數字列表的平均數,你可以檢查其結果是不是大於列表中最大的元素,或者小於最小的元素。 這被稱 作“合理性檢查”,因爲它能檢測出“不合理的”結果。

另一類檢查是比較兩個不同計算的結果,來看一下它們是否一致。這被稱作“一致性檢查”。

  • 格式化輸出
格式化調試輸出能夠更容易定位一個錯誤。 我們在調試一節中看過一個示例。pprint模塊提供了一個 pprint 函數,它可以更可讀的格式顯示內建類型( pprint 代表 “pretty print”)。












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章