2009-05-14 10 views
8

डीबगिंग करते समय, मैं किसी फ़ंक्शन के सभी इनपुट और आउटपुट प्रिंट करना पसंद करता हूं (मुझे पता है कि मुझे एक बेहतर आईडीई चाहिए, लेकिन मुझे हास्य, यह त्रुटि रिपोर्टिंग के लिए उपयोग किया जा सकता है)। तो, मैं आदर्श रूप से यह करना चाहता हूं:आप अजगर में @debuggable सजावट कैसे लिखेंगे?

@debuggable 
def myfunc(argA,argB,argC): 
    return argB+1 

और डिबगिंग को चालू या बंद करने के लिए वैश्विक चर का उपयोग करें। नहीं, आपको ग्लोबल्स पसंद नहीं है, मैंने अनुमान लगाया है।

सबसे अच्छा मैं के साथ आ सकता है:

DEBUG = True 

def debuggable(func): 
    if DEBUG: 
     def decorated(*args): 
      print "Entering ",func.func_name 
      print " args ",args 
      ret = func(*args) 
      print ret 
      return ret 
     return decorated 
    else: 
     return func 

@debuggable 
def myfunc(this,that): 
    return this+that 

और चल रहा है:

>>> myfunc(1,3) 
Entering myfunc 
    args (1, 3) 
4 

मैं ऐसा कैसे सुधार कर सकते हैं?

+0

वहाँ इस विषय पर एक काफी लंबी ब्लॉग पोस्ट है

डेकोरेटर तो अधिक की तरह कुछ लग सकता है [शब्द संरेखित] (http://wordaligned.org/articles/echo) पर सजावटी चित्रकारी का। –

उत्तर

22

एक डीबगर का उपयोग करें। गंभीरता से। आप जिस ट्रैक को ट्रैक रखना चाहते हैं उसे सजाना एक बुरा विचार है।

पायथन has a debugger included, इसलिए आपको एक अच्छी आईडीई की आवश्यकता नहीं है।

यदि आप डीबगर का उपयोग नहीं करना चाहते हैं, तो आप trace function का उपयोग कर सकते हैं।

import sys 

@sys.settrace 
def trace_debug(frame, event, arg): 
    if event == 'call': 
     print ("calling %r on line %d, vars: %r" % 
       (frame.f_code.co_name, 
       frame.f_lineno, 
       frame.f_locals)) 
     return trace_debug 
    elif event == "return": 
     print "returning", arg 

def fun1(a, b): 
    return a + b 

print fun1(1, 2) 

प्रिंट यही कारण है कि:

यह, कई एक नेटवर्क पर एक मंच स्वतंत्र चित्रमय जीपीएल अजगर दूरस्थ डीबगिंग के लिए समर्थन के साथ डीबगर है:

calling 'fun1' on line 14, vars: {'a': 1, 'b': 2} 
returning 3 
3 

भी आसान Winpdb उपयोग करने के लिए किया जाएगा धागे, नामस्थान संशोधन, एम्बेडेड डीबगिंग, एन्क्रिप्टेड संचार और पीडीबी से 20 गुना तेज है।

विशेषताएं:

  • जीपीएल लाइसेंस। Winpdb मुफ्त सॉफ्टवेयर है।
  • सीपीथॉन 2.3 या उसके बाद के संस्करण के साथ संगत।
  • WxPython 2.6 या उसके बाद के संस्करण के साथ संगत।
  • प्लेटफार्म स्वतंत्र, और उबंटू गत्सी और विंडोज एक्सपी पर परीक्षण किया गया।
  • उपयोगकर्ता इंटरफेस: rpdb2 कंसोल आधारित है, जबकि winpdb को wxPython 2.6 या बाद की आवश्यकता होती है।

Screenshot http://winpdb.org/images/screenshot_winpdb_small.jpg

6

मैं एक डिबगर का उपयोग कर nosklo से सहमत अपनी खुद लिखने की तुलना में काफी बेहतर है। मैं आपके कोड में सुधार पोस्ट करूंगा। लेकिन मुझे अभी भी लगता है कि आपको नोस्लो की सलाह का पालन करना चाहिए।

class Debugger(object): 
    enabled = False 
    def __init__(self, func): 
     self.func = func 

    def __call__(self, *args, **kwargs): 
     if self.enabled: 
      print 'Entering', self.func.func_name 
      print ' args:', args, kwargs 
     return self.func(*args, **kwargs) 

Debugger.enabled = True 

@Debugger 
def myfunc(a, b, c, d): 
    pass 
0

मैं दूसरा क्या nosklo ने कहा:

उपयोग डेकोरेटर कक्षाएं अपने डिबगर neater बनाने के लिए।

सूचना के लिए एक और बात अपने कार्य थोड़ा खतरनाक है:

b = myfunc(1,3) 

इस मामले में, "बी" None, है सजाया समारोह कुछ भी वापस नहीं करता है क्योंकि।

7

मुझे लगता है कि आप क्या कर रहे हैं वास्तव में एक डिबगिंग सजावट नहीं है, लेकिन एक लॉगिंग सजावट के अधिक है।

Python's logging module का उपयोग करना समझ में आता है ताकि आप लॉगिंग पर अधिक बढ़िया नियंत्रण प्राप्त कर सकें। उदाहरण के लिए आप बाद में आउटपुट का विश्लेषण करने के लिए फ़ाइल में आउटपुट करने में सक्षम होंगे।

 

import logging 

logger = logging.getLogger('TraceLog') 
# TODO configure logger to write to file/stdout etc, it's level etc 


def logthis(level): 
    def _decorator(fn): 
     def _decorated(*arg,**kwargs): 
      logger.log(level, "calling '%s'(%r,%r)", fn.func_name, arg, kwargs) 
      ret=fn(*arg,**kwargs) 
      logger.log(level, "called '%s'(%r,%r) got return value: %r", fn.func_name, arg, kwargs, ret) 
      return ret 
     return _decorated 
    return _decorator 

@logthis(logging.INFO) 
def myfunc(this,that): 
    return this+that 
 

तो अगर आप उत्पादन के लिए लकड़हारा कॉन्फ़िगर stderr करने के लिए आप देखना चाहते हैं:

 

>>> logger.setLevel(logging.INFO) 
>>> handler=logging.StreamHandler() 
>>> logger.addHandler(handler) 
>>> myfunc(1,2) 
calling 'myfunc'((1, 2),{}) 
called 'myfunc'((1, 2),{}) got return value: 3 
 
संबंधित मुद्दे