혹시 프로그래머이신가요? 만약 그렇다면, 디버깅은 사용하는 프로그래밍 언어와 상관없이 반드시 필요한 기술입니다. 이 글에서는 Python에서 assert
구문을 활용하여 디버깅 효율을 높이는 방법을 소개합니다.
프로젝트를 진행하다 보면 여러 모듈을 만들게 되죠. 함수, 클래스 정의 등이 그 예입니다. 이때 코드에 버그가 발생하여 오류나 예상치 못한 결과가 나타날 수 있습니다. assert
구문은 이러한 상황에서 코드를 디버깅하는 데 매우 유용합니다.
본 튜토리얼에서는 assert
구문의 사용법과 실제 코드 예제를 통해 작동 원리를 알아볼 것입니다. 또한 어설션 에러가 무엇인지, 그리고 이를 활용하여 개발 과정에서 코드의 오류를 수정하는 방법까지 자세히 다룰 예정입니다.
그럼, 시작해 볼까요!
Python에서 assert
구문 사용법
assert
구문의 문법을 살펴본 후, 몇 가지 코드 예제를 통해 실습해 보겠습니다.
assert
구문 문법
Python에서 assert
구문을 사용하는 기본 문법부터 알아봅시다.
assert 표현식, 메시지
여기서,
표현식
은 평가할 Python 유효 표현식입니다. 변숫값, 변수의 참/거짓 여부, 함수의 반환값 등에 대한 조건이 될 수 있습니다.- 표현식이
True
로 평가되는 동안,assert
구문은 아무런 오류를 발생시키지 않거나 반환값 없이 정상적으로 작동합니다. 이는 프로그램이 기대대로 동작하고 있다는 것을 의미합니다. - 만약 표현식이
True
가 아니면,AssertionError
예외가 발생합니다. 메시지
는 선택적인 문자열입니다.AssertionError
예외 발생 시 역추적에 표시할 메시지를 지정할 수 있습니다.
다음으로, assert
구문이 어떻게 더 깔끔하고 버그 없는 코드를 작성하는 데 도움을 주는지 몇 가지 예시 코드를 통해 알아봅시다.
이 튜토리얼에서 사용된 코드 예시는 GitHub gist에서 확인하실 수 있습니다.
Python assert
구문 예시
다음 예시를 살펴봅시다. 코드에 discount
변수가 있다고 가정합니다. 이 값은 항상 max_discount
보다 작거나 같아야 합니다.
실수로 discount
변수를 잘못된 값으로 설정하지 않았는지 확인하기 위해 어설션을 추가할 수 있습니다. 평가할 표현식은 discount <= max_discount
입니다.
>>> max_discount = 50
>>> discount = 20
>>> assert discount <= max_discount
여기서 discount
(20)는 max_discount
(50)보다 작으므로 assert
구문은 오류를 발생시키지 않습니다.
AssertionError
예외
만약 discount
변수가 max_discount
보다 큰 값으로 설정되면 AssertionError
예외가 발생합니다.
>>> discount = 75
>>> assert discount <= max_discount
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
assert
구문에는 선택적 메시지 문자열을 지정할 수 있다는 것을 배웠습니다.
더 자세한 진단 정보를 제공하는 메시지 문자열도 사용해 보겠습니다. discount
와 max_discount
값을 포함하는 Python f-string을 assert
구문에 추가해 보겠습니다.
>>> assert discount <= max_discount, f"할인은 최대 {max_discount}이어야 합니다. 현재 할인값 = {discount}"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: 할인은 최대 50이어야 합니다. 현재 할인값 = 75
위 출력에서 볼 수 있듯이 AssertionError
예외에 이제 discount
및 max_discount
변수의 값이 포함되어 있습니다.
assert
를 이용한 Python 함수 디버깅 및 테스트
함수를 정의할 때, 의도치 않게 함수가 예상대로 작동하지 못하게 만드는 버그(논리적 오류)를 만들 수 있습니다.
예를 들어, 수업 중에 시험을 보고 학생들이 보너스 문제를 풀 기회를 얻는 상황을 가정해 봅시다. 보너스 문제를 푼 학생은 시험에서 10점을 추가로 받습니다. 😄
다음 get_final_score
함수를 생각해 보겠습니다.
- 현재 점수, 추가 점수, 그리고 보너스 문제 풀이 여부(boolean)를 입력으로 받습니다.
- 만약 학생이 보너스 문제를 풀었다면(boolean 값이
True
), 현재 점수에 10점을 추가합니다. - 그 후, 최종 점수를 반환합니다.
def get_final_score(score, bonus):
if bonus:
score += 10
return score
이제 함수를 몇 번 호출해 보겠습니다. bonus
가 True
및 False
로 설정된 경우, 각각 점수가 34점과 40점이면 최종 점수는 44점과 40점이 됩니다.
print(get_final_score(34, True))
# 44
print(get_final_score(40, False))
# 40
하지만 시험의 최대 점수는 50점입니다. 따라서 학생이 49점을 받고 보너스 문제도 풀었다면, get_final_score
함수는 최종 점수를 59점으로 계산합니다.
print(get_final_score(49, True))
# 59
기술적으로는 가능하지만, 학생이 시험에서 얻을 수 있는 최대 점수 이상을 받을 수 없다고 가정해 보겠습니다. 🙂
이제 max_score
변수를 초기화하고, 함수에서 반환된 점수를 final_score
변수에 저장합니다.
그 후, final_score
가 max_score
보다 작은지 확인하는 어설션을 추가합니다.
def get_final_score(score, bonus):
if bonus:
score += 10
return score
final_score = get_final_score(47, True)
max_score = 50
assert final_score <= max_score
이제 함수 호출 get_final_score(47, True)
에 대해 AssertionError
예외가 발생합니다.
Traceback (most recent call last):
File "main.py", line 17, in <module>
assert final_score <= max_score
AssertionError
이제 f-string
을 추가하여 assert
구문에 오류 메시지를 추가해 보겠습니다.
assert final_score <= max_score,f"최종 점수는 최대 {max_score}점이어야 합니다. 현재 점수 = {final_score}"
Traceback (most recent call last):
File "main.py", line 17, in <module>
assert final_score <= max_score,f"최종 점수는 최대 {max_score}점이어야 합니다. 현재 점수 = {final_score}"
AssertionError: 최종 점수는 최대 50점이어야 합니다. 현재 점수 = 57
함수 수정
이제 get_final_score
함수 정의를 수정하여 예상치 못한 동작을 수정해 봅시다.
get_final_score
함수는max_score
도 매개변수로 사용합니다.- 보너스가
True
인지 확인하고, 맞으면score
변수에 10점을 추가합니다. - 그 후, 점수가
max_score
보다 큰지 확인합니다. 만약 그렇다면max_score
를 반환합니다. - 그렇지 않으면
score
를 반환합니다.
이제 최종 점수가 항상 max_score
보다 작거나 같도록 했습니다.
def get_final_score(score, bonus, max_score):
if bonus:
score += 10
if score > max_score:
return max_score
return score
빠른 연습으로, 함수가 이제 예상대로 작동하는지 확인하는 몇 가지 어설션을 작성해 보세요.
AssertionError
예외에 대한 참고 사항
표현식이 False
로 평가되면 AssertionError
예외가 발생하지만, 이러한 오류를 예외로 처리하지 않도록 주의해야 합니다. 이는 다음과 같은 코드를 작성해서는 안 된다는 것을 의미합니다.
try:
<이 작업을 수행>
except AssertionError:
<이 작업을 수행>
get_final_score
의 이전 예제에서 어설션을 사용하여 final_score
가 max_score
보다 작은지 확인했습니다. 그 후, 어설션 에러가 발생하지 않도록 함수 정의를 수정했습니다.
이것이 어설션의 목적입니다. 어설션은 코드의 온전성을 검사하는 것이며, 더 깔끔한 코드를 작성하는 데 도움이 됩니다. 반면, 예외 처리는 런타임에 발생하는 예기치 않은 오류를 예상하고 처리하는 것입니다. 여기에는 잘못된 입력 타입이나 값이 포함되는 경우가 많습니다.
요약하자면, 효과적인 디버깅을 위해 Python assert
구문을 사용해야 하며, AssertionError
를 예외로 처리해서는 안 됩니다.
결론
이 튜토리얼이 Python에서 assert
구문을 사용하는 방법을 이해하는 데 도움이 되었기를 바랍니다. 배운 내용을 요약해 보겠습니다.
- Python
assert
구문(어설션)은assert 표현식
형태를 취합니다. 표현식이True
인지 확인합니다. 만약True
로 평가되지 않으면AssertionError
예외가 발생합니다. assert 표현식, 메시지
구문으로assert
를 사용할 수도 있습니다. 이는AssertionError
예외가 발생할 때마다 메시지 문자열을 출력합니다.- 어설션 오류를 처리하기 위해 예외 처리를 구현해서는 안 된다는 것을 기억해야 합니다. 어설션을 코드의 온전성을 검사하는 유용한 디버깅 도구로 사용하세요.
개발자로서 어설션은 디버깅에 큰 도움이 됩니다. 프로젝트의 모든 개별 구성 요소(모듈)가 예상대로 작동하는지 확인하기 위해 Python에서 단위 테스트를 작성하는 방법을 배우는 것을 추천합니다.
다음으로, 시도해 볼 수 있는 초급 Python 프로젝트 목록을 확인해 보세요.