2011-12-15 15 views
10

क्या gdb में disp के बराबर एक पीडीबी है?पायथन पीडीबी (डीबगर) disp बराबर?

उदा। जब मैं gdb का उपयोग कर सी डिबगिंग कर रहा हूँ मैं टाइप करके कोड के माध्यम से हर 'कदम' पर छपी चर हो सकता है:

disp var 

जब मैं pdb का उपयोग कर रहा इसी तरह की सुविधा चाहते हैं अजगर डिबगिंग हूँ, लेकिन disp प्रतीत नहीं होता वहां रहने के लिए, अजगर पीडीबी दस्तावेज एक विकल्प प्रदान नहीं करता है - लेकिन यह एक अजीब चूक की तरह लगता है?

+0

शायद ipdb, कुछ वैकल्पिक कार्यक्षमता – bph

+0

एक विकल्प के रूप है अगर आप एक अच्छा यूआई चाहें, तो आप उपयोग कर सकते हैं [ pudb] (https://pypi.python.org/pypi/pudb)। –

उत्तर

1

पीडीबी डीबगिंग के दौरान आप एक अक्षर कमांड से परे सामान्य पायथन कोड टाइप कर सकते हैं - इसलिए केवल print var का उपयोग करना आपके लिए काम करना चाहिए।

+0

का अर्थ यह होगा कि प्रत्येक बार जब मैं 's' या' n' दबाता हूं तो पीडीबी स्वचालित रूप से 'var' को फिर से मुद्रित कर देगा? यह सुनिश्चित नहीं है कि यह मेरे लिए 'p var' टाइप करने जैसा ही लगता है। सवाल यह नहीं है कि डीबगर का उपयोग करके एक चर मुद्रित करने के तरीके के बारे में, मैं पीडीबी का अधिक कुशलतापूर्वक/प्रभावी ढंग से उपयोग कैसे कर सकता हूं ... – bph

+0

क्षमा करें - नहीं - यह केवल एक बार चर को प्रिंट करता है। – jsbueno

+0

ठीक है - मेरा नया जवाब यह करना चाहिए। – jsbueno

3

कोड bellow अजगर आत्मनिरीक्षण सुविधाओं का उपयोग करता डिबगिंग शुरू करने से पहले इस मॉड्यूल PDB मॉड्यूल के लिए दो नए आदेश जोड़ने 0 सिर्फ दिए गए समारोह, और एक अलग मॉड्यूल में अपने कॉल रखा, और आयात करने के लिए - आप 'disp होना चाहिए 'और' undisp 'कमांड चर के लिए घड़ियों को जोड़ और वापस लेते हैं।

यह पाइथन के पीडीबी मॉड्यूल को बंदरपैचिंग द्वारा काम करता है, जो शुद्ध पायथन में लिखा गया है।

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

दुर्भाग्य से मैं केवल यह चर की स्थिति प्रदर्शित के रूप में वे पिछले आदेश के निष्पादन के लिए पहले से कहां से कर सकता है। (मैंने थोड़ा सा प्रयास किया, लेकिन बीडीबी मॉड्यूल को बंद कर दिया, जो कि पीडीबी का आधार भी काम नहीं कर रहा था)। आप किसी भी pdb.pdb, bdb.bdb या cmd.Cmd में विधियों को आजमा सकते हैं और बदल सकते हैं जिन्हें wrap द्वारा सजाया गया है जिसे डिबग किए गए फ्रेम स्थिति के बाद बुलाया गया है।

3

आप कुछ उपनाम है कि आप के लिए यह कर देगा सेट कर सकते हैं:

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

चर नाम की एक पूरी सूची मुद्रण पाठक के लिए एक व्यायाम के रूप में छोड़ दिया जाता है। दुर्भाग्यवश ऐसा करने का अर्थ यह है कि जब आप डीबगर को खाली रेखा भेजते हैं, तो "अंतिम आदेश" निष्पादित करता है, उदाहरण के लिए n, "" निष्पादित करता है। आपको लगता है कि ठीक करने के लिए चाहते हैं, तो आप यह कुछ हद तक hacky सेट 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')"