調試你的Python代碼

調試你的Python代碼

譯自: http://howchoo.com/g/zgi2y2iwyze/debugging-your-python-code 
作者: Ashley 
    當你不得不更新別人的代碼時,你有多少次陷入這樣一種境地?如果你是一個開發團隊的一員,那我猜一定多于你愿意的次數。 結果我們發現Python (和其他語言一樣)提供了在這種情況下便利的debug特性。愿這份快速指南能使你的生活輕松些。

1 一段糟糕的代碼

   出于本教程段目的讓我們假設如下一段簡單段程序。這段程序獲取兩個命令行參數以及加減操作。 (讓我們假設用戶輸入的參數無誤,因此無需處理異常)

import sys
def add(num1=0, num2=0):
    return int(num1) + int(num2)
def sub(num1=0, num2=0):
    return int(num1) - int(num2)
def main():
    #Assuming our inputs are valid numbers
    print sys.argv
    addition = add(sys.argv[1], sys.argv[2])
    print addition
    subtraction = sub(sys.argv[1], sys.argv[2])
    print subtraction
if __name__ == '__main__':
    main()

2 加入pdb

Python自帶了名為pdb的,基于交互的源碼debug模塊。
你需要已如下方式啟用該模塊。 

import pdb
pdb.set_trace()

 加入斷點(break points) 的示例程序:

import pdb
import sys
def add(num1=0, num2=0):
    return int(num1) + int(num2)
def sub(num1=0, num2=0):
    return int(num1) - int(num2)
def main():
    #Assuming our inputs are valid numbers
    print sys.argv
    pdb.set_trace() # <-- Break point added here
    addition = add(sys.argv[1], sys.argv[2])
    print addition
    subtraction = sub(sys.argv[1], sys.argv[2])
    print subtraction
if __name__ == '__main__':
    main()

# /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb)

我們會看到下次被執行的將是第15行。
程序在執行第15行前暫停了。
我們在這里有一些選擇。。。讓我們在接下來的步驟中展示其中一部分。

4 下一行 -> n

在debugger提示符處 按”n” 會到下一行。

> /Users/someuser/debugger.py(14)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) n
> /Users/someuser/debugger.py(15)main()
-> print addition

 這會執行當前行并準備好執行下一行。
我們雖然能夠通過使用”n” 來一行行執行程序,但這樣不是太有用。
你可能已經注意到了pdb實際上并沒有進入add函數中。讓我們在看看debugger的其他選項,使排錯變得更有趣。 

 注意:
 另一個酷酷的特性是按回車鍵會執行你之前執行過的命令(本例中為”n”)。

5 打印 ->p

讓我們再次開始debug吧?。热晃覀儧]有任何程序會執行完。你可以敲擊”c”使pdb跳至最后或者下一個斷點(break point) 

['debugger.py', '1', '2']
> /Users/someuser/debugger.py(14)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb)

現在如果我們想知道sys.argv包含了哪些參數,我們可以這么干:

-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) p sys.argv
['debugger.py', '1', '2']
(Pdb) p sys.argv[1]
'1'
(Pdb)

 這在檢測變量實際存儲的值時非常有用。
現在讓我們進入add函數內部

6 進入函數 -> s

我們可以通過使用”s”來進入我們的addition函數。

(Pdb) s
--Call--
> /Users/someuser/debugger.py(4)add()
-> def add(num1=0, num2=0):
(Pdb) n
> /Users/someuser/debugger.py(5)add()
-> return int(num1) + int(num2)
(Pdb)

 這使我們來到了add函數的內部,現在我們能夠在其中使用”n, p”以及其他操作了。
這時敲擊”r”會跳轉至所進入函數的返回語句處。(譯注:再次敲擊時會跳轉至函數調用處)
這在你想快速跳轉至方法結尾時很有用。

7 動態添加斷點(break point) -> b

我們在運行程序前通過pdb.set_trace()設置了斷點(break point)
通常在debugger開始后,我們會想在一些特定的位置設置斷點(break point)
好基友 “b” 登場。
讓我們再次執行我們的程序

['debugger.py', '1', '2']
> /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb)

現在我在第18行設置一個斷點(break point)。

-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) b 18
Breakpoint 1 at /Users/someuser/debugger.py:18
(Pdb) c
We are in add--
3
> /Users/someuser/debugger.py(18)main()
-> print subtraction
(Pdb) p subtraction
-1
(Pdb)

如我們所見,pdb直接跳至第18行并等待進一步指令。
pdb也會給斷點賦一個數字(本例中為數字1)。我們能夠使用(原文為”user” 疑似筆誤)
enable/disable 斷點(break point)數字再進一步執行中啟用或關閉相對應的斷點(break point)。

8 列表 -> l

有時在debug的過程中,你會迷失于代碼中。此時,你可以使用”l”來輸出一個格式良好的摘要來告知你你身在何處。# 斟酌

['debugger.py', '1', '2']
> /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) l
 10
 11     def main():
 12         #Assuming our inputs are valid numbers
 13         print sys.argv
 14         pdb.set_trace() # <-- Break point added here
 15  ->     addition = add(sys.argv[1], sys.argv[2])
 16         print addition
 17         subtraction = sub(sys.argv[1], sys.argv[2])
 18         print subtraction
 

9 給變量動態賦值

在debug時,能給變量賦值也有助于排錯。
假設:

['debugger.py', '1', '2']
> /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) n
We are in add--
> /Users/someuser/debugger.py(16)main()
-> print addition
(Pdb) p addition
3 #<--- addition here is 3
(Pdb) addition = 'this is now string' #<--- We changed the value of additon
(Pdb) n
this is now string #<--- Now when we print it we actually gets it as a string. that we just set above.
> /Users/someuser/debugger.py(17)main()
-> subtraction = sub(sys.argv[1], sys.argv[2])

注意:
如果你想給像”n”這樣的變量賦值(即同時也是pdb 命令),你需要這樣做:

(Pdb) !n=5
(Pdb) p n
5

10 退出 -> q

最后你可以通過”q”,在任何時刻退出。程序執行會被終止。

11 擴展閱讀

本文僅僅觸及pdb的表面。還有更多的文檔在向你招手!
那些使用ipython的能夠在ipdb中找到更好的debugger:tab補全,語法高亮以及其他酷酷的特性。
如果你有其他使用pdb的有趣方法請在下面評論
排錯愉快!

原創文章,作者:octopus,如若轉載,請注明出處:http://www.www58058.com/1395

(0)
octopusoctopus
上一篇 2015-03-23 17:02
下一篇 2015-03-23 21:39

相關推薦

  • Python內置數據結構——字符串

    知識結構圖 學習筆記 字符串 字符組成的有序序列,字符的集合 使用單引號、雙引號、三引號引起來的字符序列 不可變對象 Unicode類型 定義 單引號、雙引號、三引號 r、R:引號內的字符原樣輸出 元素訪問 索引訪問 可迭代 join連接 “string“.join(iteratable) 使用string作為分隔符將可迭代對象連接起…

    2018-03-31
  • Python的安裝

    安裝Python 3還是2目前,Python有兩個版本,一個是2.x版,一個是3.x版,這兩個版本是不兼容的。由于3.x版越來越普及,3中的特性越來越要求企業用3來開發,所以更加推薦python3作為安裝學習的版本??梢栽谀男┎僮飨到y下安裝python安裝Python的平臺因為Python是跨平臺的,它可以運行在Windows、Mac和各種Linux/Uni…

    2017-09-18
  • Python數據結構

    數據結構個人總結,方便以后查找。

    Python筆記 2018-04-01
  • enumerate用法和轉置矩陣求解、效率測試

    enumerate用法和轉置矩陣求解、效率測試

    2018-04-08
  • 文件操作

    文件操作 馮諾依曼體系架構 CPU由運算器和控制器組成 運算器,完成各種算數的運算,邏輯運算,數據傳輸等數據加工處理 控制器,控制程序的執行 存儲器,用于記憶程序的數據,列如內存 輸入設備,將數據或者程序輸入到計算機中列如鍵盤 鼠標 輸出設備,將數據或者程序的處理結果展示給用戶,列如顯示器,打印機等等 ? 一般說的IO操作,指的是文件的IO,如果是指網絡的I…

    Python筆記 2018-05-02
  • DevOps 風向標!DevOps國際峰會6月29日正式啟航!

    DOIS 大會為您呈現互聯網公司與海外企業的實踐經驗與工具技術,聚焦 DevOps 在金融、電信、零售等行業的系統性實踐。在這里我們不空談、不務虛,實實在在的專注DevOps落地。

    2018-05-16
欧美性久久久久