在gdb中是否有相當於disp
的pdb?Python的pdb(調試器)disp等效?
例如當我用gdb調試C我可以通過鍵入印有通過代碼的每個「步驟」變量:
disp var
當我使用PDB我想類似的功能調試Python,但disp
似乎並不在那裏,python pdb文檔似乎沒有提供一個替代方案 - 但它看起來像是一個奇怪的遺漏?
在gdb中是否有相當於disp
的pdb?Python的pdb(調試器)disp等效?
例如當我用gdb調試C我可以通過鍵入印有通過代碼的每個「步驟」變量:
disp var
當我使用PDB我想類似的功能調試Python,但disp
似乎並不在那裏,python pdb文檔似乎沒有提供一個替代方案 - 但它看起來像是一個奇怪的遺漏?
在pdb調試期間,您可以輸入正常的python代碼,超出一個字母命令 - 所以只需使用print var
應該適合您。
下面的代碼使用Python內省功能向PDB模塊添加兩個新命令0 只需將給定的函數及其調用放在單獨的模塊中,並在開始調試之前導入此模塊 - 您應該擁有「disp '和'undisp'命令會將手錶添加到變量並將其撤回。
它通過monkeypatching Python的pdb模塊,它是用純python編寫的。
# -*- coding: utf-8 -*-
def patch_pdb():
import pdb
def wrap(func):
def new_postcmd(self, *args, **kw):
result = func(self, *args, **kw)
if hasattr(self, "curframe") and self.curframe and hasattr(self, "watch_list"):
for arg in self.watch_list:
try:
print >> self.stdout, "%s: %s"% (arg, self._getval(arg)) + ", ",
except:
pass
self.stdout.write("\n")
return result #func(self, *args, **kw)
return new_postcmd
pdb.Pdb.postcmd = wrap(pdb.Pdb.postcmd)
def do_disp(self, arg):
if not hasattr(self, "watch_list"):
self.watch_list = []
self.watch_list.append(arg)
pdb.Pdb.do_disp = do_disp
def do_undisp(self, arg):
if hasattr(self, "watch_list"):
try:
self.watch_list.remove(arg)
except:
pass
pdb.Pdb.do_undisp = do_undisp
patch_pdb()
if __name__ == "__main__":
# for testing
import pdb; pdb.set_trace()
a = 0
for i in range(10):
print i
a += 2
不幸的是,我只能讓它顯示變量的狀態,因爲他們以前執行最後一個命令。 (我嘗試了一下,但monkypatching bdb模塊,這是Pdb的基礎似乎也沒有工作)。您可以嘗試更改由wrap
修飾的pdb.Pdb,bdb.Bdb或cmd.Cmd中的方法,以找到調試幀狀態更改後調用的方法。
您可以設置一些別名,會爲你做到這一點:
alias n next;; p var
alias s step;; p var
打印變量名稱的整個列表作爲練習留給讀者。不幸的是,這樣做意味着當您向調試器發送空行時,它執行的「最後一個命令」是p var
,而不是例如n
。如果要解決這個問題,那麼你就可以在PDB命令,而不是使用這個有點哈克集:
!global __stack; from inspect import stack as __stack
!global __Pdb; from pdb import Pdb as __Pdb
!global __pdb; __pdb = [__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self") for __framerec in __stack() if (__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self")).__class__ == __Pdb][-1]
alias s step;; p var;; !__pdb.lastcmd = "!__pdb.cmdqueue.append('s')"
alias n next;; p var;; !__pdb.lastcmd = "!__pdb.cmdqueue.append('n')"
也許IPDB具有一定的替代性功能 – bph 2011-12-19 14:52:37
作爲替代方案,如果你喜歡一個漂亮的UI,你可能需要使用[ pudb](https://pypi.python.org/pypi/pudb)。 – 2014-08-05 19:25:38