print()로 디버깅하는 것은 소규모 스크립트에서는 충분하지만, ML 프로젝트에서는 학습 로그, 에러 추적, 실험 기록을 체계적으로 관리해야 합니다. logging 모듈은 로그 레벨별 필터링, 파일 저장, 포맷 지정을 제공하며, pdb는 코드 실행을 중단하고 변수 상태를 검사할 수 있는 강력한 디버거입니다.
import logging# 기본 설정 (한 번만 호출)logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S",)# 로거 생성logger = logging.getLogger(__name__)# 로그 레벨별 사용logger.debug("디버그 메시지 (개발 중 상세 정보)")logger.info("정보 메시지 (정상 동작 기록)")logger.warning("경고 메시지 (잠재적 문제)")logger.error("에러 메시지 (기능 오류)")logger.critical("치명적 메시지 (시스템 중단)")
2
로그 레벨 이해
레벨
숫자
용도
예시
DEBUG
10
개발 중 상세 정보
변수 값, 함수 호출 추적
INFO
20
정상 동작 기록
학습 시작, epoch 완료
WARNING
30
잠재적 문제
메모리 사용량 높음, 학습률 너무 큼
ERROR
40
기능 오류
파일 못 찾음, API 실패
CRITICAL
50
시스템 중단
GPU 메모리 부족, 디스크 꽉 참
프로덕션에서는 INFO 이상, 개발 중에는 DEBUG 레벨로 설정하는 것이 일반적입니다.
3
포맷 문자열
Copy
# 주요 포맷 코드format_str = "%(asctime)s [%(levelname)-8s] %(name)s:%(lineno)d - %(message)s"# 출력: 2024-06-15 14:30:25 [INFO ] __main__:42 - 학습 시작# 주요 포맷 코드 목록# %(asctime)s - 시간 (2024-06-15 14:30:25)# %(levelname)s - 레벨 이름 (INFO, WARNING 등)# %(name)s - 로거 이름# %(filename)s - 파일명# %(lineno)d - 줄 번호# %(funcName)s - 함수명# %(message)s - 로그 메시지
# 방법 1: breakpoint() 사용 (Python 3.7+, 권장)def calculate_loss(predictions, targets): total_loss = 0 for pred, target in zip(predictions, targets): diff = pred - target breakpoint() # 여기서 실행 중단, 디버거 진입 total_loss += diff ** 2 return total_loss / len(predictions)# 방법 2: pdb 직접 사용import pdbdef find_bug(data): result = [] for item in data: pdb.set_trace() # breakpoint()과 동일 processed = item * 2 result.append(processed) return result
print는 항상 stdout으로 출력되며 제어가 불가능합니다. logging은 레벨별 필터링, 파일/콘솔/네트워크 등 다양한 출력 대상, 포맷 지정, 프로덕션에서 레벨 변경이 가능합니다. print는 디버깅 후 지워야 하지만, logging은 레벨을 올려 무시할 수 있습니다.
VS Code에서 디버거를 사용하는 방법은?
VS Code의 Python 확장은 시각적 디버거를 제공합니다. 줄 번호 옆을 클릭하여 중단점을 설정하고, F5로 디버깅을 시작하면 변수 검사, 호출 스택 확인, 조건부 중단점 등을 GUI로 사용할 수 있습니다. launch.json에서 인자와 환경 변수를 설정합니다.