Python 에서 함수가 예외를 발생시키는지 확인하는 방법

PythonBeginner
지금 연습하기

소개

이 랩에서는 Python 에서 함수가 예외를 발생시키는지 확인하는 방법을 배우게 됩니다. 랩은 예외와 함수 내에서 예외가 발생할 수 있는 방식을 탐구하는 것으로 시작합니다. ZeroDivisionError를 발생시킬 수 있는 간단한 Python 함수를 만들고 예외가 발생할 때의 트레이스백 (traceback) 을 관찰합니다.

다음으로, 예외를 우아하게 처리하기 위해 try-except 블록을 구현합니다. 마지막으로, 함수가 특정 예외를 발생시키는지 테스트하기 위해 pytest.raises를 사용하는 방법을 배웁니다 (선택적 소개).

함수 내 예외 탐구

이 단계에서는 Python 에서 예외와 함수 내에서 예외가 발생할 수 있는 방식을 배우게 됩니다. 견고하고 신뢰할 수 있는 코드를 작성하려면 예외를 이해하는 것이 중요합니다. 예외는 프로그램 실행의 정상적인 흐름을 방해하는 이벤트입니다. 잘못된 입력, 파일을 찾을 수 없음 또는 네트워크 오류 등 다양한 이유로 발생할 수 있습니다.

예외를 발생시킬 수 있는 간단한 Python 함수를 만들어 보겠습니다. LabEx 환경에서 VS Code 편집기를 열고 ~/project 디렉토리에 exceptions_example.py라는 새 파일을 만듭니다.

## ~/project/exceptions_example.py
def divide(x, y):
    return x / y

print(divide(10, 2))
print(divide(5, 0))

이 코드에서:

  • 두 개의 인자 xy를 받아 xy로 나눈 결과를 반환하는 divide라는 함수를 정의합니다.
  • 먼저 인자 102divide 함수를 호출합니다. 그러면 콘솔에 5.0이 출력됩니다.
  • 그런 다음 인자 50으로 divide 함수를 호출합니다. 이렇게 하면 0 으로 나누는 것은 허용되지 않으므로 ZeroDivisionError가 발생합니다.

이제 이 스크립트를 실행해 보겠습니다. VS Code 에서 터미널을 열고 ("View" -> "Terminal"에서 찾을 수 있습니다) 다음 명령을 실행합니다.

python ~/project/exceptions_example.py

다음과 유사한 출력을 볼 수 있습니다.

5.0
Traceback (most recent call last):
  File "/home/labex/project/exceptions_example.py", line 4, in <module>
    print(divide(5, 0))
  File "/home/labex/project/exceptions_example.py", line 2, in divide
    return x / y
ZeroDivisionError: division by zero

보시다시피 첫 번째 print 문은 성공적으로 실행되었고 결과 5.0이 출력되었습니다. 그러나 divide 함수가 y = 0으로 호출되었을 때 ZeroDivisionError가 발생했고 프로그램이 종료되었습니다. 트레이스백은 예외로 이어진 함수 호출 시퀀스를 보여주며, 이는 디버깅에 도움이 될 수 있습니다.

이 예제는 함수 내에서 예외가 발생할 수 있고 프로그램의 정상적인 흐름을 어떻게 방해할 수 있는지 보여줍니다. 다음 단계에서는 tryexcept 블록을 사용하여 예외를 처리하는 방법을 배우게 됩니다.

try-except 블록 구현

이전 단계에서 예외로 인해 프로그램이 갑자기 종료될 수 있음을 확인했습니다. 예외를 우아하게 처리하고 프로그램 충돌을 방지하려면 tryexcept 블록을 사용할 수 있습니다.

try 블록을 사용하면 예외를 발생시킬 수 있는 코드 섹션을 묶을 수 있습니다. try 블록 내에서 예외가 발생하면 프로그램은 해당 except 블록으로 이동하여 예외를 처리할 수 있습니다.

ZeroDivisionError를 처리하기 위해 try-except 블록을 포함하도록 exceptions_example.py 파일을 수정해 보겠습니다. VS Code 편집기에서 exceptions_example.py 파일을 열고 다음과 같이 수정합니다.

## ~/project/exceptions_example.py
def divide(x, y):
    try:
        result = x / y
        return result
    except ZeroDivisionError:
        return "Cannot divide by zero!"

print(divide(10, 2))
print(divide(5, 0))
print(divide(8, 4))

이 수정된 코드에서:

  • x / y 연산 주위에 try 블록을 추가했습니다. 즉, 나눗셈 중에 ZeroDivisionError가 발생하면 프로그램이 except 블록으로 이동합니다.
  • except ZeroDivisionError: 줄은 ZeroDivisionError 예외를 처리하려는 것을 지정합니다.
  • except 블록 내부에서 문자열 "Cannot divide by zero!"를 반환합니다. 이렇게 하면 프로그램이 충돌하는 대신 콘솔에 출력됩니다.

이제 수정된 스크립트를 실행해 보겠습니다. VS Code 에서 터미널을 열고 다음 명령을 실행합니다.

python ~/project/exceptions_example.py

다음과 유사한 출력을 볼 수 있습니다.

5.0
Cannot divide by zero!
2.0

보시다시피, 프로그램은 더 이상 0 으로 나눌 때 충돌하지 않습니다. 대신 except 블록이 ZeroDivisionError를 포착하고 메시지 "Cannot divide by zero!"가 출력됩니다. 그런 다음 프로그램은 계속 실행되고 마지막 print 문도 성공적으로 실행됩니다.

try-except 블록은 다른 유형의 예외를 처리하는 데에도 사용할 수 있습니다. 예를 들어, 호환되지 않는 데이터 유형에 대한 연산을 시도할 경우 발생할 수 있는 TypeError 예외를 처리하기 위해 try-except 블록을 사용할 수 있습니다. 또한 다른 유형의 예외를 처리하기 위해 여러 개의 except 블록을 가질 수도 있습니다.

다음 단계에서는 pytest를 사용하여 예외를 테스트하는 방법에 대해 배우게 됩니다.

pytest.raises 로 테스트 (선택적 소개)

이 선택적 단계에서는 pytest를 사용하여 예외를 테스트하는 방법에 대한 간략한 소개를 제공합니다. pytest는 Python 을 위한 널리 사용되는 테스트 프레임워크로, 테스트를 작성하고 실행하는 프로세스를 단순화합니다.

먼저 pytest를 설치해 보겠습니다. VS Code 에서 터미널을 열고 다음 명령을 실행합니다.

pip install pytest

이 명령은 pytest와 해당 종속성을 다운로드하여 설치합니다.

이제 divide 함수에 대한 테스트 파일을 만들어 보겠습니다. ~/project 디렉토리에 test_exceptions.py라는 새 파일을 만듭니다.

## ~/project/test_exceptions.py
import pytest
from exceptions_example import divide

def test_divide_by_zero():
    with pytest.raises(ZeroDivisionError):
        divide(5, 0)

def test_divide_valid():
    assert divide(10, 2) == 5

이 코드에서:

  • pytest 모듈과 exceptions_example.py 파일에서 divide 함수를 가져옵니다.
  • test_divide_by_zero라는 테스트 함수를 정의합니다. 이 함수는 pytest.raises를 사용하여 divide(5, 0)을 호출하면 ZeroDivisionError가 발생함을 단언합니다. with pytest.raises(ZeroDivisionError): 블록은 블록 내에서 ZeroDivisionError가 발생할 경우에만 테스트가 통과되도록 합니다.
  • test_divide_valid라는 다른 테스트 함수를 정의합니다. 이 함수는 divide(10, 2)를 호출하면 값 5를 반환함을 단언합니다.

테스트를 실행하려면 VS Code 에서 터미널을 열고 다음 명령을 실행합니다.

pytest ~/project/test_exceptions.py

다음과 유사한 출력을 볼 수 있습니다.

============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.4.4, pluggy-1.3.0
rootdir: /home/labex/project
collected 2 items

test_exceptions.py ..                                                      [100%]

============================== 2 passed in 0.01s ===============================

출력은 두 개의 테스트가 수집되었고 두 테스트 모두 통과했음을 보여줍니다. 이는 divide 함수가 예상대로 작동함을 나타냅니다. 0 으로 나눌 때는 ZeroDivisionError를 발생시키고, 0 이 아닌 숫자로 나눌 때는 올바른 결과를 반환합니다.

이것은 pytest를 사용하여 예외를 테스트하는 매우 기본적인 예입니다. pytest에는 더 포괄적이고 효과적인 테스트를 작성하는 데 도움이 되는 많은 다른 기능이 있습니다.

요약

이 랩에서는 Python 함수에서 예외를 탐구하는 것으로 시작하여 예외가 프로그램의 정상적인 흐름을 방해하는 이벤트임을 이해합니다. 0 으로 나눌 때 ZeroDivisionError를 발생시키는 divide 함수를 만듭니다. 스크립트를 실행하면 예외가 프로그램의 종료를 어떻게 유발하고 디버깅을 위한 추적 (traceback) 을 제공하는지 보여줍니다.

이 랩은 견고한 코드를 작성하기 위해 예외를 이해하는 것의 중요성을 강조하며, 예외를 발생시킬 수 있는 함수의 간단한 예와 예외가 발생할 때 결과 오류 및 추적을 관찰하는 방법을 보여줍니다.