1. 程式人生 > >除錯和編寫程式方法

除錯和編寫程式方法

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

錯誤資訊會很多,但是通常有用部分是:

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

增量式開發(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”)。