코드 디버깅 기술

Beginner

This tutorial is from open-source community. Access the source code

소개

코드는 완벽할 수 없습니다. 항상 버그가 발생할 것입니다. 코드 디버깅은 반드시 익혀야 할 기술입니다.

디버깅 팁

자, 프로그램이 충돌했습니다...

$ python3 blah.py
Traceback (most recent call last):
  File "blah.py", line 13, in ?
    foo()
  File "blah.py", line 10, in foo
    bar()
  File "blah.py", line 7, in bar
    spam()
  File "blah.py", 4, in spam
    line x.append(3)
AttributeError: 'int' object has no attribute 'append'

이제 어떻게 해야 할까요?!

Traceback 읽기

마지막 줄은 충돌의 구체적인 원인입니다.

## Cause of the crash

하지만, 항상 읽거나 이해하기 쉬운 것은 아닙니다.

PRO TIP: 전체 traceback 을 Google 에 붙여넣으세요.

REPL 사용하기

스크립트를 실행할 때 Python 을 유지하려면 -i 옵션을 사용하세요.

$ python3 -i blah.py
Traceback (most recent call last):
  File "blah.py", line 13, in ?
    foo()
  File "blah.py", line 10, in foo
    bar()
  File "blah.py", line 7, in bar
    spam()
  File "blah.py", 4, in spam
    line x.append(3)
AttributeError: 'int' object has no attribute 'append'
>>>

이것은 인터프리터 상태를 유지합니다. 즉, 충돌 후에도 주변을 탐색할 수 있습니다. 변수 값 및 기타 상태를 확인합니다.

Print 로 디버깅하기

print() 디버깅은 매우 흔하게 사용됩니다.

팁: repr()을 사용하세요.

def spam(x):
    print('DEBUG:', repr(x))
    ...

repr()은 값의 정확한 표현을 보여줍니다. 예쁘게 출력되는 것은 아닙니다.

>>> from decimal import Decimal
>>> x = Decimal('3.4')
## NO `repr`
>>> print(x)
3.4
## WITH `repr`
>>> print(repr(x))
Decimal('3.4')
>>>

Python 디버거

프로그램 내에서 수동으로 디버거를 실행할 수 있습니다.

def some_function():
    ...
    breakpoint()      ## Enter the debugger (Python 3.7+)
    ...

이것은 breakpoint() 호출에서 디버거를 시작합니다.

이전 Python 버전에서는 다음과 같이 했습니다. 다른 디버깅 가이드에서 이 내용을 언급하는 것을 볼 수 있습니다.

import pdb
...
pdb.set_trace()       ## Instead of `breakpoint()`
...

디버거에서 실행하기

전체 프로그램을 디버거에서 실행할 수도 있습니다.

$ python3 -m pdb someprogram.py

첫 번째 문장 전에 자동으로 디버거에 진입합니다. 중단점을 설정하고 구성을 변경할 수 있습니다.

일반적인 디버거 명령어:

(Pdb) help            ## Get help
(Pdb) w(here)         ## Print stack trace
(Pdb) d(own)          ## Move down one stack level
(Pdb) u(p)            ## Move up one stack level
(Pdb) b(reak) loc     ## Set a breakpoint
(Pdb) s(tep)          ## Execute one instruction
(Pdb) c(ontinue)      ## Continue execution
(Pdb) l(ist)          ## List source code
(Pdb) a(rgs)          ## Print args of current function
(Pdb) !statement      ## Execute statement

중단점의 위치는 다음 중 하나입니다.

(Pdb) b 45            ## Line 45 in current file
(Pdb) b file.py:45    ## Line 45 in file.py
(Pdb) b foo           ## Function foo() in current file
(Pdb) b module.foo    ## Function foo() in a module

연습 문제 8.4: 버그? 무슨 버그?

실행됩니다. 배포하세요!

요약

축하합니다! 디버깅 랩을 완료했습니다. LabEx 에서 더 많은 랩을 연습하여 기술을 향상시킬 수 있습니다.