디버깅을 위해서만 print 문 사용


109

저는 늦게 파이썬으로 많은 코딩을했습니다. 그리고 저는 이전에 작업하지 않았던 데이터로 작업하고 있으며, 이전에는 볼 수 없었던 공식을 사용하고 거대한 파일을 처리했습니다. 이 모든 것이 제대로 진행되고 있는지 확인하고 실패 지점을 식별하기 위해 많은 인쇄 문을 작성하게했습니다. 그러나 일반적으로 너무 많은 정보를 출력하는 것은 좋은 습관이 아닙니다. 디버깅하려는 경우에만 print 문을 사용하고 인쇄하지 않으려면 건너 뛰도록하려면 어떻게해야합니까?

답변:


161

logging모듈은 당신이 원하는 수있는 모든 것을 갖추고 있습니다. 처음에는 과도 해 보일 수 있지만 필요한 부분 만 사용하십시오. 내가 사용하는 것이 좋습니다 것 logging.basicConfig로깅 수준 전환 stderr하고 간단한 로그 방법 , debug, info, warning, errorcritical.

import logging, sys
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
logging.debug('A debug message!')
logging.info('We processed %d records', len(processed_records))

5
또한 저처럼이 모듈을 설치하는 데 문제가있는 경우; 로깅은 표준 라이브러리의 일부입니다. 가상 환경을 사용하는 경우에도 pip 설치가 필요하지 않습니다.
Amr

오류 만 인쇄하고 디버그 메시지는 표시하지 않도록 로깅 수준을 어떻게 설정합니까?
Eduardo Pignatelli

@EduardoPignatelli levelbasicConfig호출 에서을 logging.ERROR.
Matt Joiner

jupyter lab 1.2.6에서는 작동하지 않습니다. 로깅 수준은 한 번만 설정할 수 있으며 사용중인 재설정은 logging.basicConfig(stream=sys.stderr, level=logging.ERROR)효과가 없습니다. 커널을 다시 시작하고 새 수준을 설정하면 작동하지만 그게 저에게는 해결 방법입니다.
Eduardo Pignatelli

@EduardoPignatelli 당신은 이것에 대해 다른 질문을해야합니다. 그러나 루트 로거에서 레벨을 직접 변경해야 할 가능성이 높습니다. jupyter가 사용자보다 먼저 basicConfig를 호출 할 것입니다.
Matt Joiner

28

이를 수행하는 간단한 방법은 로깅 함수를 호출하는 것입니다.

DEBUG = True

def log(s):
    if DEBUG:
        print s

log("hello world")

그런 다음 DEBUG로깅을 사용하거나 사용하지 않고 코드 의 값을 변경 하고 실행할 수 있습니다.

표준 logging모듈에는 이에 대한보다 정교한 메커니즘이 있습니다.


5
장기적으로는 제공되는 로깅 모듈 을 사용하는 것이 자체적으로 롤링 하는 것보다 더 낫습니다 (더 복잡해 보이지만).
mgiuca 2011

11
사실이지만 어떻게 스스로 굴릴 있는지 이해하는 것은 가치 가 있습니다.
Greg Hewgill 2011-07-05

1
과연. 위의 내용은 logging(매우 간단한 수준에서) 어떻게 작동 하는지에 대한 좋은 아이디어입니다 .
mgiuca

이것은 내 aws 람다에 사용하는 것입니다.
crsuarezf

21

인쇄 대신 로깅 내장 라이브러리 모듈을 사용하십시오 .

당신은 만들 Logger개체 (말을 logger), 당신은 디버그 프린트를 삽입 할 때마다 그 후, 당신은 넣어 :

logger.debug("Some string")

logger.setLevel프로그램 시작시 사용 하여 출력 레벨을 설정할 수 있습니다. DEBUG로 설정하면 모든 디버그가 인쇄됩니다. INFO 이상으로 설정하면 즉시 모든 디버그가 사라집니다.

또한 다른 수준 (정보, 경고 및 오류)에서 더 심각한 사항을 기록하는 데 사용할 수도 있습니다.


12

먼저, 저는 파이썬의 로깅 프레임 워크를 두 번째로 지명 할 것 입니다. 그러나 사용 방법에 대해 약간주의하십시오. 특히 : 로깅 프레임 워크가 변수를 확장하도록 허용하고 직접 수행하지 마십시오. 예를 들어 다음 대신 :

logging.debug("datastructure: %r" % complex_dict_structure)

다음을 확인하십시오.

logging.debug("datastructure: %r", complex_dict_structure)

비슷해 보이지만 첫 번째 버전은 비활성화 된 경우에도 repr () 비용 이 발생하기 때문 입니다. 두 번째 버전은 이것을 피합니다. 마찬가지로, 직접 굴려도 다음과 같은 것을 제안합니다.

def debug_stdout(sfunc):
    print(sfunc())

debug = debug_stdout

다음을 통해 호출 :

debug(lambda: "datastructure: %r" % complex_dict_structure)

다시 한 번 다음을 수행하여 비활성화하면 오버 헤드를 피할 수 있습니다.

def debug_noop(*args, **kwargs):
    pass

debug = debug_noop

이러한 문자열을 계산하는 오버 헤드는 1) 계산에 비용이 많이 들거나 2) 디버그 문이 n ^ 3 루프 등의 중간에 있지 않는 한 중요하지 않습니다. 나는 그것에 대해 아무것도 알지 못합니다.


로깅 하우투의 '최적화'아래에이 중요한 주제에 대한 자세한 정보가 있습니다. docs.python.org/3/howto/logging.html#optimization
Martin CR

7

나는 다른 사람에 대해 잘 모르겠지만, 내가 정의하는 데 사용했다 "글로벌 상수" ( DEBUG) 다음 전역 함수 ( debug(msg)인쇄 할) msg경우에만를 DEBUG == True.

그런 다음 다음과 같이 디버그 문을 작성합니다.

debug('My value: %d' % value)

... 그런 다음 단위 테스트를 선택하고 다시는하지 않았습니다! :)


단위 테스트 하. 좋아, 또 다른 한가지는 다음 :( 포착 할 수 이잖아
crazyaboutliv

1
단위 테스트를 권장하지 않고 필수입니다. 하지만 디버깅 기술이라 할지라도 로깅을 대체 할 수 없다고 생각합니다. 빠르게 테스트하기 위해 여전히 많은 인쇄 작업을합니다.
mgiuca

@crazyaboutliv-제대로 된 단위 테스트는 훌륭합니다. 간단하고 간결하며 따라하기 쉬운 프레젠테이션을 위해 파이썬에 대한 이 장 을 살펴보십시오
mac

@mgiuca-저도 빠른 인쇄를하지만 print()테스트를 통과하는 데 필요한 수준으로 코드를 가져 오는 동안 몇 번 정도입니다 . 나는 print()모든 곳 에서 엄청난 양으로 끝나지 않습니다 . 로깅도 멋지다! :)
mac

2
@mac 이제 링크에 명시적인 'www'가 필요한 것 같습니다 . 이제 여기에서 호스팅됩니다 .
culix
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.