2009-05-14 2 views
8

디버깅 할 때 함수의 모든 입력과 출력을 인쇄하고 싶습니다 (더 나은 IDE가 필요하다는 것을 알고 있지만 유머가 나옵니다. 오류보고에 사용될 수 있습니다).파이썬에서 @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

데코레이터는 더 같이 보일 수 있습니다 [Word Aligned] (http://wordaligned.org/articles/echo)에서 데코레이터를 추적합니다. –

답변

22

디버거를 사용하십시오. 진지하게. 추적하고 싶은 모든 기능을 꾸미는 것은 나쁜 생각입니다.

파이썬 has a debugger included이므로 좋은 IDE가 필요하지 않습니다.

디버거를 사용하지 않으려면 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) 

인쇄한다 :

그것은 네트워크를 통해 다수의 원격 디버깅에 대한 지원과 함께 플랫폼 독립적 그래픽 GPL 파이썬 디버거이다

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

더 쉬운 방법은 Winpdb를 사용하는 것 스레드, 네임 스페이스 수정, 임베디드 디버깅, 암호화 된 통신 등이 있으며 pdb보다 최대 20 배 빠릅니다.

특징 :

  • GPL 라이센스. Winpdb는 자유 소프트웨어입니다.
  • CPython 2.3 이상과 호환됩니다.
  • wxPython 2.6 이상과 호환됩니다.
  • 플랫폼 독립적이며 Ubuntu Gutsy 및 Windows XP에서 테스트되었습니다.
  • 사용자 인터페이스 : rpdb2는 콘솔 기반이지만 winpdb는 wxPython 2.6 이상이 필요합니다.

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

6

내가 디버거를 사용하여 nosklo에 동의은 자신을 쓰는 것보다 훨씬 낫다. 코드에 개선점을 게시하겠습니다. 하지만 니콜로의 조언을 따라야한다고 생각해. 내가 두 번째 말 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

:

사용 데코레이터 클래스는 디버거 깔끔한 모양을 확인합니다.

주목해야 할 또 다른 점은 함수가 조금 위험하다입니다 : 장식 기능이 아무것도 반환하지 않기 때문에이 경우

b = myfunc(1,3) 

는, "B"는 None입니다.

7

필자는 디버깅 데코레이터가 아니라 로깅 데코레이터를 더 많이 사용한다고 생각합니다.

Python's logging module을 사용하면 로깅 자체를보다 세부적으로 제어 할 수 있습니다. 예를 들어 나중에 출력을 분석하기 위해 파일로 출력 할 수 있습니다. 당신은 stderr로 출력 로거를 구성하는 경우 당신이 볼 것 그리고

 

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 
 

: 상당히 긴 블로그 게시물이 주제에이

 

>>> 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 
 
관련 문제