Python 디버깅: `newprint` (ver 0.9)
- 이 글은 <예전 글: Python 디버깅: `print` 함수 가로채기>을 수정/보완했습니다.
디버깅
디버깅은 프로그래머의 숙명이다.
사람들은 프로그래머가 하는 일의 80%가 디버깅이라고도 한다.
Python과 디버깅
파이썬을 쓰면서 불편한 점의 하나는 디버깅이다. 특히 실행하는데 시간이 많이 걸리는 프로그램의 경우는 실행 과정을 계속 앉아서 모니터링하기 힘들기 때문에 여러 가지 수단을 마련해야 한다. 한가지 방법은 출력을 화일로 저장하는 것이다. 하지만 어떻게?
몇 가지 가능성
- Redirect stout to a file in Python
- 유닉스를 쓴다면, 유닉스 차원에서 모든 출력과 에러 메시지를 화일로 보낸다.
python3 -u foo.py 2>&1 | tee log.txt
- Python logging module를 사용한다.
위의 방법들을 시도해 본 결과, 모두 그다지 만족스럽지 못했다.
- 표준출력
stout
을 화일로 보내는 것은 생각보다 잘 되지 않았다. python3 -u foo.py 2>&1 | tee filename.txt
의 경우는 가장 간단하게 쓸 수 있는 방법이지만, 실행 시간이 길어지면filename.txt
가 용량이 지나치게 커지는 문제가 생긴다.logging
은 좋은 방법이지만, 기존의 소스를 고쳐야 한다는 문제가 있다. 그리고logging
을 사용하는 방법을 배워야 한다!
newprint.py
그래서 기존의 print
를 그대로 쓸 수 있는 방법을 고안하게 되었다. 다음을 newprint.py
로 저장한 후, print
를 사용하여 디버깅에 필요한 내용을 화면과 화일에 동시에 출력하고자 할 때, 코드의 첫 머리에 import newprint
, from newprint import print
만 삽입하면, print
내용이 log_년-월-일.py
로 저장된다.
# save the following as newprint.py from datetime import datetime, date import sys print0 = print def print2(*argv, sep=' ', end='\n', file=sys.stdout, flush=False, **kwarg): """ python의 print를 가로채서 화면과 log file에 동시에 출력합니다. version 0.9(2020-12-07) Args: end : what will be printed at the end file : log filename """ file_debug = kwarg.pop('file_debug', fnDebug) if file_debug != fnDebug: f_debug = open(file_debug, 'a') else: f_debug = fDebug #file = kwarg.pop('file', sys.stdout) if len(kwarg.keys()) > 0: raise ValueError('Unknown arguments found ' + ''.join(kwarg.keys())) if not noprint_display and file is sys.stdout: print0(*argv, sep = sep, end = end, file=file, flush = flush, **kwarg) if not noprint_file and file is not sys.stdout: print0(*argv, sep = sep, end = end, file=file, flush = flush, **kwarg) if not noprint_debug: print0(*argv, sep = sep, end = end, file=f_debug, flush = flush, **kwarg, ) # debug = True # if debug: print = print2 today = date.today() fnDebug = 'log_'+today.strftime("%Y-%m-%d")+'.txt' fDebug = open(fnDebug, 'a') noprint_display = False noprint_file = False noprint_debug = False
예를 들어 다음과 같이 쓰는 것이다.
import newprint from newprint import print0, print2, print from datetime import datetime, date today = date.today() print('Current time : ', today)
log
화일 변경
만약 프로그램이 하루를 넘어 실행되어 log-().txt
의 날짜를 바꿔야 한다면 다음의 루틴으로 가능하다.
today = date.today() if (today > newprint.today): newprint.fDebug.close() newprint.today = today newprint.fnDebug = 'log_'+today.strftime("%Y-%m-%d")+'.txt' newprint.fDebug = open(newprint.fnDebug, 'a')
그 밖의 설정
newprint.noprint_display = True
:cron
에 사용된다면, 스크린에 출력되는 아웃풋 자체를 소거하는 게 나을 수 있다.newprint.noprint_file = True
: file로 출력되는 부분만 소거한다newprint.noprint_debug = True
: log 화일만 억제한다.
테스팅
import newprint from newprint import print0, print2, print newprint.fnDebug='test-newprint-debug.txt' newprint.fDebug=open(newprint.fnDebug, 'a') file = open('test-newprint-file.txt', 'a') print('*** testing_newprint') print('*** testing_newprint', file=file) print('*** testing_newprint', file_debug='test-newprint-debug2.txt') newprint.noprint_display = True print('testing_newprint with noprint_display') print('testing_newprint with noprint_display', file=file) print('testing_newprint with noprint_display', file_debug='test-newprint-debug2.txt') newprint.noprint_display = False newprint.noprint_file = True print('testing_newprint with noprint_file') print('testing_newprint with noprint_file', file=file) print('testing_newprint with noprint_file', file_debug='test-newprint-debug2.txt') newprint.noprint_display = True newprint.noprint_file = True print('testing_newprint with noprint_file and noprint_display') print('testing_newprint with noprint_file and noprint_display', file=file) print('testing_newprint with noprint_file and noprint_display', file_debug='test-newprint-debug2.txt') newprint.noprint_display = False newprint.noprint_file = False newprint.noprint_debug = True print('testing_newprint with noprint_debug') print('testing_newprint with noprint_debug', file=file) print('testing_newprint with noprint_debug', file_debug='test-newprint-debug2.txt') print = print0 # back to original print print('test ending: check the files...') print('- test-newprint-debug.txt') print('- test-newprint-debug2.txt') print('- test-newprint-file.txt')```
마무리
- 혹시 좀 더 나은 방법이 있다면 댓글로 알려주세요!
Leave a comment