복붙노트

[PYTHON] 어떻게 파이썬에서 @debuggable 데코레이터를 작성하겠습니까?

PYTHON

어떻게 파이썬에서 @debuggable 데코레이터를 작성하겠습니까?

디버깅 할 때 함수의 모든 입력과 출력을 인쇄하고 싶습니다. (더 나은 IDE가 필요하다는 것을 알고 있지만 유머가 나와 오류보고에 사용될 수 있습니다.) 그래서, 나는 이상적으로 갖고 싶어 :

@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

어떻게 향상시킬 수 있습니까?

해결법

  1. ==============================

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

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

    파이썬에는 디버거가 포함되어 있으므로 좋은 IDE가 필요하지 않습니다.

    디버거를 사용하지 않으려면 추적 기능을 사용할 수 있습니다.

    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를 사용하는 것이 더 쉽습니다.

    그것은 플랫폼 독립적 인 그래픽 GPL 파이썬 디버거로 네트워크, 다중 쓰레드, 네임 스페이스 수정, 임베디드 디버깅, 암호화 된 통신을 통한 원격 디버깅을 지원하며 pdb보다 최대 20 배 빠릅니다.

    풍모:

    스크린 샷 http://winpdb.org/images/screenshot_winpdb_small.jpg

  2. ==============================

    2.제 생각에는 디버깅 데코레이터가 아니라 로깅 데코레이터라고 생각합니다.

    제 생각에는 디버깅 데코레이터가 아니라 로깅 데코레이터라고 생각합니다.

    파이썬의 로깅 모듈을 사용하면 로깅 자체를보다 세밀하게 제어 할 수 있습니다. 예를 들어 나중에 출력을 분석하기 위해 파일로 출력 할 수 있습니다.

    데코레이터는 다음과 같은 모양이 될 수 있습니다.

    
    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
    
    
  3. ==============================

    3.나는 디버거를 사용하는 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
    
  4. ==============================

    4.nosklo가 말한 것에서 두 번째.

    nosklo가 말한 것에서 두 번째.

    주의해야 할 또 다른 점은 함수가 약간 위험하다는 것입니다.

    b = myfunc(1,3)
    

    이 경우 데코 레이팅 된 함수가 아무 것도 반환하지 않기 때문에 "b"는 None입니다.

  5. from https://stackoverflow.com/questions/862807/how-would-you-write-a-debuggable-decorator-in-python by cc-by-sa and MIT license