1. 程式人生 > >命令列下 pdb 除錯 Python 程式

命令列下 pdb 除錯 Python 程式

 

官方參考網站 The Python Debugger : https://docs.python.org/3/library/pdb.html
gdb 除錯命令的使用及總結:https://blog.csdn.net/freeking101/article/details/54406982
使用 Pdb 除錯 Python:https://segmentfault.com/a/1190000006628456

 

 

命令列下 pdb 除錯 Python 程式

 

Python提供類似於C++ gdb 的除錯工具 pdb,可以使用 pdb 在命令列下進行 Python 程式的除錯。 

使用 Pdb 除錯 Python的程式的方式主要是下面的三種
1. 命令列加 -m 引數:python -m pdb testPdb.py
2. 在python互動環境除錯
        >>> import pdb
        >>> import testPdb
        >>> pdb.run('testPdb.test()')
3. 程式碼中插入一段程式。
比較常用的,就是在程式中間插入一段程式,相對於在一般 IDE 裡面打上斷點然後啟動 debug,不過這種方式是 hardcode 的

if __name__ == "__main__":
    a = 1
    import pdb
    pdb.set_trace()
    b = 2
    c = a + b
    print(c)

然後正常執行指令碼: python testPdb.py ,程式執行到 pdb.set_trace() 就會暫停下來,然後就可以看到除錯的提示符 (Pdb)了

 

下面介紹這三種方法:

1. 單步執行程式碼,通過命令 python -m pdb xxx.py 啟動指令碼,進入單步執行模式。即命令列啟動目標程式時加上 -m 引數。

這樣程式會自動停在第一行,等待你進行除錯

我們可以使用除錯命令進行除錯,和使用IED除錯類似。 

 pdb命令列:

    1)進入命令列Debug模式,python -m pdb xxx.py
    2)h:(help)幫助
    3)w:(where)列印當前執行堆疊
    4)d:(down)執行跳轉到在當前堆疊的深一層(個人沒覺得有什麼用處)
    5)u:(up)執行跳轉到當前堆疊的上一層
    6)b:(break)新增斷點
                 b 列出當前所有斷點,和斷點執行到統計次數
                 b line_no:當前指令碼的line_no行新增斷點
                 b filename:line_no:指令碼filename的line_no行新增斷點
                 b function:在函式function的第一條可執行語句處新增斷點
    7)tbreak:(temporary break)臨時斷點
                 在第一次執行到這個斷點之後,就自動刪除這個斷點,用法和b一樣
    8)cl:(clear)清除斷點
                cl 清除所有斷點
                cl bpnumber1 bpnumber2... 清除斷點號為bpnumber1,bpnumber2...的斷點
                cl lineno 清除當前指令碼lineno行的斷點
                cl filename:line_no 清除指令碼filename的line_no行的斷點
    9)disable:停用斷點,引數為bpnumber,和cl的區別是,斷點依然存在,只是不啟用
    10)enable:啟用斷點,引數為bpnumber
    11)s:(step)執行下一條命令
                如果本句是函式呼叫,則s會執行到函式的第一句
    12)n:(next)執行下一條語句
                如果本句是函式呼叫,則執行函式,接著執行當前執行語句的下一條。
    13)r:(return)執行當前執行的函式直到結束。即執行到函式返回
    14)c:(continue)繼續執行,直到遇到下一條斷點
    15)l:(list)列出原始碼
                 l 列出當前執行語句周圍11條程式碼
                 l first 列出first行周圍11條程式碼
                 l first second 列出first--second範圍的程式碼,如果second<first,second將被解析為行數
    16)a:(args)列出當前執行函式的函式
    17)p expression:(print)輸出expression的值
    18)pp expression:好看一點的p expression
    19)run:重新啟動debug,相當於restart
    20)q:(quit)退出debug
    21)j lineno:(jump)設定下條執行的語句函式
                只能在堆疊的最底層跳轉,向後重新執行,向前可直接執行到行號
    22)unt:(until)執行到下一行(跳出迴圈),或者當前堆疊結束
    23)condition bpnumber conditon,給斷點設定條件,當引數condition返回True的時候bpnumber斷點有效,否則bpnumber斷點無效
    24)bt : 檢視呼叫堆疊資訊

注意:
    1:直接輸入Enter,會執行上一條命令;
    2:輸入PDB 不認識的命令,PDB 會把他當做 Python語句 在當前環境下執行;

 

方法2:在程式中設定 pdb 除錯:

示例程式碼(這裡使用 selenium 驅動瀏覽器,然後得到 cookies ):
python selenium 用法 和 Chrome headless:https://blog.csdn.net/freeking101/article/details/70056173

注意:需要匯入 pdb 包

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author      : 
# @File        : mao_yan_cookies.py
# @Software    : PyCharm
# @description : XXX


import pdb
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import selenium.webdriver.support.ui as ui

# from selenium.webdriver.common.action_chains import ActionChains

# chrome_options = webdriver.ChromeOptions()
# # chrome_options.add_argument('--headless')
# browser = webdriver.Chrome(chrome_options=chrome_options)
# # 開啟瀏覽器 設定等待載入時間 訪問URL
# wait = ui.WebDriverWait(browser, 10)


# def test_1():
#     browser.get('https://www.baidu.com/')
#     print('開啟瀏覽器')
#     print(browser.title)
#     browser.find_element_by_id('kw').send_keys('測試')
#     print('關閉')
#     browser.quit()
#     print('測試完成')
#
#
# def test_2():
#     url = "https://www.newrank.cn/public/info/list.html?period=pgcweek&type=data"
#     browser.get(url)
#     print(browser.page_source)  # 列印渲染後的頁面程式碼
#
#
# def test_3():
#     url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
#     browser.get(url)
#     browser.switch_to.frame('iframeResult')  # 切換到 巢狀的 html 頁面
#     source = browser.find_element_by_css_selector('#draggable')
#     print(source)
#     try:
#         logo = browser.find_element_by_class_name('logo')
#     except NoSuchElementException:
#         print('NO LOGO')
#     browser.switch_to.parent_frame()  # 返回到父 html 頁面
#     logo = browser.find_element_by_class_name('logo')
#     print(logo)
#     print(logo.text)


class MaoYanCookies(object):
    def __init__(self):
        super(MaoYanCookies, self).__init__()
        chrome_options = webdriver.ChromeOptions()
        # chrome_options.add_argument('--headless')
        self.browser = webdriver.Chrome(chrome_options=chrome_options)
        # 開啟瀏覽器 設定等待載入時間 訪問URL
        self.wait = ui.WebDriverWait(self.browser, 10)
        pass

    def get_cookies(self):
        cinema_url = 'http://maoyan.com/cinema/15280'
        self.browser.get(cinema_url)
        base_time_element = self.browser.find_element_by_xpath('//table[@class="plist"]//tbody//td//a')
        base_time_url = base_time_element.get_attribute('href')
        print(base_time_url)
        self.browser.get(base_time_url)
        cookies = self.browser.get_cookies()
        print(cookies)
        pass

    def __del__(self):
        self.browser.close()


if __name__ == "__main__":
    # test_1()
    # test_2()
    # test_3()
    pdb.set_trace()   # <-- Break point added here,設定的斷點
    myc = MaoYanCookies()
    myc.get_cookies()
    pass

在程式中需要打斷點處新增 pdb.set_trace()  ,這樣程式會在 pdb.set_trace() 暫停並進入 pdb 除錯環境,可以用 “p 變數名” 檢視變數,或者 c 繼續執行

命令列直接輸入命令:python mao_yan_cookies.py,然後 回車

 

 

 

Python -- pdb除錯工具

 

From:http://www.bubuko.com/infodetail-1860030.html

學c++時,老師教我們有gdb除錯工具,在工作中會經常用到;
學shell時,經理讓我見到了"-x"跟蹤除錯引數,我每天都會用到;
學python後,我就在尋找類似的引數和工具,谷歌給了我pdb工具;

 

【簡介除錯工具】

 

pdb
使用如下程式碼就相當於新增斷點了:

import pdb    
pdb.set_trace()  #設定斷點的地方,放置於程式中

 

ipdb
相對於python ,我們更趨向於ipython,有漂亮的顏色,和<tab>補全提示,以及bash混用;
相對於python內建的pdb,ipdb 的優勢也正在於此,其實就是對 ipython 的呼叫:

使用時需要先安裝 ipdb 包:pip install ipdb

import ipdb
ipdb.set_trace()

而 ipdb 用法和 pdb 類似,只是更友好,更直觀,如下:  

 

pudb
是全屏的基於控制檯的視覺化偵錯程式,有點像c語言中的Turbo C樣式

為了支援pudb,需要在程式碼中插入:from pudb import set_trace; set_trace()  or  import pudb

 

rpdb
上面的兩種方案要求有終端輸出的情況下可行,有時候我們需要以後臺形式執行python,此時是沒有輸出互動的,比如 django 開發,程式由uwsgi管理執行,標準輸出已重定向,通常只能通過日誌輸出資訊。這個時候我們就需要一個遠端除錯工具。
rpdb會開啟一個socket連線,用於遠端除錯,預設埠是4444:

import rpdb
rpdb.set_trace(port=12345)

這樣當程式被hang住之後,會監聽該埠,可遠端連線進行除錯:
nc 127.0.0.1 12345

 

ripdb
rpdb只是pdb的遠端版本,而ripdb就是將rpdb和ipdb的功能進行了整合,既有遠端除錯功能,又有漂亮的程式碼顏色:

import ripdb
ripdb.set_trace(port=12345)

如果還需要<Tab>自動補全功能,還需要對終端進行一下設定:
SAVED_STTY=`stty -g`; stty -icanon -opost -echo -echoe -echok -echoctl -echoke; nc 127.0.0.1 12345; stty $SAVED_STTY