우리 많은 이에게 파이썬 코드 디버깅은 print 문 추가하고 출력 기반으로 무슨 일인지 추론하는 것으로 귀결됩니다. 이상적이진 않지만, 어떤 이유에서인지 사람들은 파이썬 디버거 건드리기 싫어합니다.
목차
print 문으로 디버깅
print로 디버깅하는 분들, 비판하지 않습니다. 파이썬 학습 어렵고, 프로그래밍 어렵고, 인생도 어렵습니다. 이미 힘겨운데 또 새 것 배우는 게 지루하게 느껴지는 거 이해합니다. 프린트 문 코드에 추가하는 건… 그냥 쉽습니다. 작은 고백: 저도 여전히 항상 그렇게 합니다. 일부가 말하는 것만큼 나쁘진 않습니다.
그렇다 해도, 프린트 문 추가만큼 쉽지만 무한한 디버깅 파워를 주고, 원하면 세계 정복도 가능하게 할 작은 트릭 가르쳐 드리겠습니다.
파이썬 디버거 중단점 설정
코드 제대로 디버깅하려고 IDE 필요 없습니다. 이 트릭은 가장 단순한 에디터에서도, 주피터 노트북에서도 항상 작동합니다.
트릭은 이겁니다: breakpoint() 명령으로 소위 중단점(breakpoint) 설정. 프린트 문 보통 넣던 지점 어디든, 어떤 에디터나 IDE 쓰든 코드에 삽입 가능.
그럼 무슨 일이 벌어질까요? 봅시다! 아래 같은 간단 프로그램 생성:
def add_two(x):
return x + 2
for i in range(1, 10):
a = add_two(i)
breakpoint()
print(a)
이걸 실행하면, REPL, 명령줄, IDE 어디에서 실행하든 파이썬 디버거 PDB로 진입합니다. 근데 이제 어쩌죠?
이해 쉽게: step은 함수 호출 진입해 그 함수 내부에서 중단. 반면 next는 함수가 반환될 때까지 실행하고 다음 줄에서 중단.
다른 디버거/IDE들도 이걸 'step into'(step 대신), 'step over'(next 대신)라 부름.
이제 둘 써봅시다:
$ python3 breakpointing.py
-> print(a)
(Pdb) s
3
-> for i in range(1, 10):
(Pdb) s
-> a = add_two(i)
(Pdb) n
-> breakpoint()
(Pdb) n
-> print(a)
(Pdb) n
4
-> for i in range(1, 10):
(Pdb) s
-> a = add_two(i)
(Pdb) s
--Call--
-> def add_two(x):
(Pdb) s
-> return x + 2
(Pdb) s
--Return--
5
-> return x + 2
(Pdb) s
-> breakpoint()
(Pdb)
보듯, n으로 add_two 호출 스텝 오버. 두 번째엔 s로 함수 내부로 스텝 인.
파이썬 디버거 명령어
직접 해볼 더 많은 명령어 있습니다. 다 나열 안 하고 가장 유용한 것들:
h (help): 사용 가능 모든 명령 출력. 인자도 받음, 예: h c는 c 명령 기능 설명
c (continue): 다음 중단점까지 실행 계속
l (list): 현재 줄 주변 소스 코드 나열
p: 다음 표현식 결과 출력. print() 호출 대신 사용 가능
pp: 예쁘게 출력, 딕셔너리 같은 데이터 구조 출력에 유용
restart: 현재 프로그램 재시작
전체 문서는 파이썬 디버거 페이지에서 모든 명령 확인 가능.
계속 학습
이게 아주 유용할 수 있지만, IDE 제공 디버거 파고드는 게 이득. VSCode 사용자면 VSCode서 파이썬 코드 디버깅하는 법 튜토리얼 썼습니다.