2011-12-15 44 views
10

Có pdb tương đương với disp trong gdb không?Python pdb (debugger) disp tương đương?

Ví dụ: khi tôi gỡ lỗi C sử dụng gdb tôi có thể có các biến in trên mọi 'bước' thông qua các mã bằng cách gõ:

disp var 

Khi tôi gỡ lỗi python sử dụng pdb Tôi muốn chức năng tương tự, nhưng disp dường như không để được ở đó, tài liệu pdb python dường như không cung cấp một thay thế - nhưng nó có vẻ như một thiếu sót lẻ?

+0

lẽ IPdb có một số chức năng thay thế – bph

+0

Là một thay thế, nếu bạn thích một giao diện đẹp, bạn có thể muốn sử dụng [ pudb] (https://pypi.python.org/pypi/pudb). –

Trả lời

1

Trong quá trình gỡ rối pdb, bạn có thể nhập mã python bình thường, ngoài các lệnh một chữ cái - vì vậy chỉ cần sử dụng print var sẽ hoạt động cho bạn.

+0

có nghĩa là pdb sẽ tự động in lại 'var' mỗi khi tôi nhấn' s' hoặc 'n' sau đó? Không chắc chắn rằng nó sẽ có vẻ giống như gõ 'p var' cho tôi. Câu hỏi không phải là làm thế nào để in một biến bằng cách sử dụng trình gỡ lỗi, thêm về cách tôi có thể sử dụng pdb hiệu quả hơn ... – bph

+0

Xin lỗi - không - điều này chỉ in biến một lần. – jsbueno

+0

ok - câu trả lời mới của tôi nên làm điều đó. – jsbueno

3

Mã dưới đây sử dụng các tính năng hướng nội Python để thêm hai lệnh mới vào mô-đun PDB 0 chỉ cần đặt hàm đã cho và cuộc gọi của nó trong mô-đun riêng biệt và nhập mô-đun này trước khi bắt đầu gỡ lỗi - bạn nên có 'disp Các lệnh 'và' undisp 'sẽ thêm và rút lại đồng hồ thành các biến.

Nó hoạt động bằng cách bắt chước mô-đun pdb của Python, được viết bằng python tinh khiết.

# -*- 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 

Rất tiếc, tôi chỉ có thể làm cho nó hiển thị trạng thái của các biến như trước đây khi thực hiện lệnh cuối cùng. (Tôi đã thử một chút, nhưng monkeypatching các mô-đun bdb, đó là cơ sở cho Pdb dường như không hoạt động tốt). Bạn có thể thử và thay đổi các phương thức trong pdb.Pdb, bdb.Bdb hoặc cmd.Cmd được trang trí bởi wrap để tìm một phương thức được gọi sau khi trạng thái khung đã gỡ rối đã thay đổi.

3

Bạn có thể thiết lập một số bí danh mà sẽ làm việc này cho bạn:

alias n next;; p var 
alias s step;; p var 

in một danh sách toàn bộ các tên biến là trái như một bài tập cho người đọc. Thật không may khi làm theo cách này có nghĩa là khi bạn gửi trình gỡ lỗi một dòng trống, "lệnh cuối cùng" nó thực thi là p var thay vì, ví dụ: n. Nếu bạn muốn khắc phục điều đó, sau đó bạn có thể sử dụng bộ phần nào hacky này PDB lệnh thay vì:

!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')" 
Các vấn đề liên quan