Python 의 try except 로 예외 처리하기

PythonBeginner
지금 연습하기

소개

본 랩에서는 try...except 문을 사용하여 Python 에서 예외 (exception) 를 효과적으로 처리하는 방법을 배웁니다. ValueError와 같은 특정 예외를 포착하고, 여러 예외 유형을 처리하며, 프로그램 흐름을 더 잘 제어하기 위해 elsefinally 블록을 사용하는 방법을 탐구할 것입니다. 또한, 코드에서 특정 오류 조건을 알리기 위해 사용자 정의 예외 (custom exceptions) 를 발생시키는 방법도 배웁니다. 실습을 통해 견고하고 오류에 강한 Python 프로그램을 작성하는 실질적인 경험을 쌓게 될 것입니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 100%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

try except 를 사용하여 ValueError 처리하기

이 단계에서는 try...except 문을 사용하여 ValueError를 처리하는 방법을 배웁니다. ValueError는 함수가 올바른 유형이지만 부적절한 값을 가진 인수를 받을 때 발생합니다. 일반적인 예는 int() 함수를 사용하여 숫자가 아닌 문자열을 정수로 변환하려고 시도하는 경우입니다.

사용자에게 정수를 입력하라는 메시지를 표시하는 Python 스크립트를 작성할 것입니다. 입력이 유효한 정수가 아닌 경우, ValueError를 포착하고 사용자 친화적인 메시지를 표시할 것입니다.

왼쪽에 있는 WebIDE 파일 탐색기에서 ~/project 디렉토리에 있는 handle_value_error.py 파일을 찾아 엽니다. 그런 다음 다음 코드를 파일에 추가합니다.

while True:
    try:
        x = int(input('Please enter an integer: '))
        print(f'You entered: {x}')
        break
    except ValueError:
        print('That was not a valid integer. Please try again.')

파일을 저장합니다.

이제 통합 터미널을 열고 python 명령을 사용하여 스크립트를 실행합니다.

python ~/project/handle_value_error.py

스크립트는 정수를 입력하라는 메시지를 표시합니다. 먼저 hello와 같이 정수가 아닌 값을 입력하여 오류 처리가 작동하는지 확인해 보세요. 그런 다음 123과 같은 유효한 정수를 입력하여 성공적인 실행 경로를 확인합니다.

예시 출력:

Please enter an integer: hello
That was not a valid integer. Please try again.
Please enter an integer: 123
You entered: 123

이 코드에서:

  • while True: 루프는 유효한 정수가 입력될 때까지 프로그램이 계속 입력을 요청하도록 보장합니다.
  • try 블록에는 예외를 발생시킬 수 있는 코드, 특히 int(input(...)) 호출이 포함되어 있습니다.
  • try 블록에서 ValueError가 발생하면 except ValueError: 블록 내부의 코드가 실행됩니다.
  • 예외가 발생하지 않으면 print() 문이 실행되고 break가 루프를 종료합니다.

이는 try...except ValueError를 통해 프로그램이 충돌하지 않고도 잘못된 입력을 우아하게 처리할 수 있음을 보여줍니다.

다중 예외 처리하기

코드 블록은 잠재적으로 여러 유형의 예외를 발생시킬 수 있습니다. Python 에서는 여러 개의 except 절을 사용하거나 단일 except 절에 예외를 그룹화하여 여러 예외를 처리할 수 있습니다.

나눗셈을 수행하는 스크립트를 작성해 보겠습니다. 이 연산은 입력이 숫자가 아닐 경우 ValueError를, 제수 (divisor) 가 0 일 경우 ZeroDivisionError를 발생시킬 수 있습니다.

WebIDE 에서 ~/project/handle_multiple_exceptions.py 파일을 열고 다음 코드를 추가합니다. 이 버전은 각 오류 유형에 대해 별도의 except 블록을 사용합니다.

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
    print(f"Result: {result}")
except ValueError:
    print("Invalid input. Please enter integers only.")
except ZeroDivisionError:
    print("Error: Division by zero is not allowed.")

파일을 저장하고 터미널에서 실행합니다.

python ~/project/handle_multiple_exceptions.py

각 예외를 유발하기 위해 서로 다른 입력으로 스크립트를 테스트해 보세요.

  1. 정수가 아닌 값 (예: abc) 을 입력합니다.
  2. 제수 (denominator) 에 0을 입력합니다.
  3. 두 입력 모두에 유효한 정수를 입력합니다.

0 으로 나누었을 때의 예시 출력:

Enter the numerator: 10
Enter the denominator: 0
Error: Division by zero is not allowed.

또한 튜플 (tuple) 로 그룹화하여 단일 except 절로 여러 예외를 처리할 수도 있습니다. 이는 서로 다른 오류에 대해 동일한 작업을 수행할 때 유용합니다.

이제 ~/project/handle_multiple_exceptions.py의 코드를 업데이트하여 이 그룹화된 접근 방식을 사용해 보세요.

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
    print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
    print("An error occurred: Invalid input or division by zero.")

파일을 저장하고 동일한 테스트 케이스로 다시 실행하여 새롭게 통합된 오류 메시지를 관찰합니다.

else 절을 사용하여 코드 실행하기

try 문에는 선택적인 else 절이 포함될 수 있습니다. else 블록의 코드는 try 블록이 예외를 발생시키지 않고 완료된 경우에만 실행됩니다. 이는 성공 시 실행되어야 하는 코드와 기본 try 블록의 코드를 분리하는 데 유용합니다.

나눗셈 스크립트를 수정하여 else 블록을 포함해 보겠습니다.

WebIDE 에서 ~/project/try_except_else.py 파일을 열고 다음 코드를 추가합니다.

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
except (ValueError, ZeroDivisionError):
    print("An error occurred: Invalid input or division by zero.")
else:
    print("Division successful!")
    print(f"Result: {result}")

파일을 저장하고 터미널에서 실행합니다.

python ~/project/try_except_else.py

실패하는 입력과 성공하는 입력 모두로 스크립트를 테스트해 보세요.

  1. 제수 (denominator) 에 0을 입력하여 예외를 발생시킵니다.
  2. 유효한 0 이 아닌 정수를 입력하여 else 블록을 실행합니다.

예시 출력:

Enter the numerator: 10
Enter the denominator: 0
An error occurred: Invalid input or division by zero.
Enter the numerator: 10
Enter the denominator: 2
Division successful!
Result: 5.0

보시다시피, 나눗셈이 성공했을 때만 else 블록의 메시지가 출력됩니다. 예외가 발생하면 except 블록이 실행되고 else 블록은 건너뜁니다.

finally 절을 사용하여 코드 실행 보장

try 문에는 선택적인 finally 절도 있습니다. finally 블록 내부의 코드는 try 블록에서 예외가 발생했는지 여부와 관계없이 항상 실행됩니다. 이는 파일을 닫거나 리소스를 해제하는 등 모든 시나리오에서 반드시 수행되어야 하는 정리 (cleanup) 작업에 이상적입니다.

나눗셈 예제에 finally 블록을 추가해 보겠습니다.

WebIDE 에서 ~/project/try_except_finally.py 파일을 열고 다음 코드를 추가합니다.

try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    result = numerator / denominator
    print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
    print("An error occurred: Invalid input or division by zero.")
finally:
    print("Execution finished.")

파일을 저장하고 터미널에서 실행합니다.

python ~/project/try_except_finally.py

실패하는 입력과 성공하는 입력 모두로 스크립트를 실행해 보세요.

  1. 제수 (denominator) 에 0을 입력하여 예외를 발생시킵니다.
  2. 유효한 0 이 아닌 정수를 입력합니다.

예시 출력:

Enter the numerator: 10
Enter the denominator: 0
An error occurred: Invalid input or division by zero.
Execution finished.
Enter the numerator: 10
Enter the denominator: 2
Result: 5.0
Execution finished.

두 경우 모두에서 finally 블록의 "Execution finished." 메시지가 출력되는 것을 확인할 수 있습니다. finally 블록은 실행이 보장되므로 필수적인 정리 코드를 두기에 신뢰할 수 있는 위치입니다.

사용자 정의 예외 발생시키기

때로는 내장된 Python 예외가 아닌 오류 조건을 알려야 할 필요가 있습니다. 이는 raise 문을 사용하여 자체 예외를 생성하고 발생시킬 수 있습니다. 이는 애플리케이션의 오류 처리를 보다 구체적이고 설명적으로 만드는 데 유용합니다.

먼저, 내장 예외를 raise하는 방법을 살펴보겠습니다. WebIDE 에서 ~/project/raise_exception.py 파일을 열고 다음 코드를 추가합니다.

def check_positive(number):
    if number <= 0:
        raise ValueError("Input must be a positive number")
    print(f"The number {number} is positive.")

try:
    check_positive(-5)
except ValueError as e:
    print(f"Caught an exception: {e}")

try:
    check_positive(10)
except ValueError as e:
    print(f"Caught an exception: {e}")

파일을 저장하고 터미널에서 실행합니다.

python ~/project/raise_exception.py

출력 결과는 다음과 같습니다.

Caught an exception: Input must be a positive number
The number 10 is positive.

여기서 check_positive 함수는 입력이 양수가 아니면 ValueError를 발생시키고, 이는 except 블록에 의해 포착됩니다.

이제 사용자 정의 예외를 정의하고 발생시켜 보겠습니다. 사용자 정의 예외는 내장된 Exception 클래스를 상속받는 클래스입니다.

WebIDE 에서 ~/project/custom_exception.py 파일을 열고 다음 코드를 추가합니다.

class NegativeNumberError(Exception):
    """Custom exception raised for negative numbers."""
    pass

def process_positive_number(number):
    if number < 0:
        raise NegativeNumberError("Negative numbers are not allowed")
    print(f"Processing positive number: {number}")

try:
    process_positive_number(-10)
except NegativeNumberError as e:
    print(f"Caught custom exception: {e}")

try:
    process_positive_number(20)
except NegativeNumberError as e:
    print(f"Caught custom exception: {e}")

파일을 저장하고 터미널에서 실행합니다.

python ~/project/custom_exception.py

출력 결과는 다음과 같습니다.

Caught custom exception: Negative numbers are not allowed
Processing positive number: 20

이 예제에서는 자체 NegativeNumberError를 정의하고 특정 조건에서 이를 발생시켰습니다. 그런 다음 try...except 블록은 이 사용자 정의 오류 유형을 구체적으로 포착하여 오류 처리를 더욱 정밀하게 만듭니다.

요약

본 실습에서는 Python 에서 견고한 오류 처리 (error handling) 를 구현하는 방법을 배웠습니다. 먼저 try...except 블록을 사용하여 사용자 입력으로부터 특정 ValueError를 포착하는 것으로 시작했습니다. 그런 다음 여러 예외 유형을 개별적으로 또는 단일 블록에서 처리하도록 확장했습니다. 또한 예외가 발생하지 않았을 때만 코드를 실행하기 위해 else 절을 사용하고, 모든 상황에서 정리 (cleanup) 코드를 실행하기 위해 finally 절을 사용하는 방법을 배웠습니다. 마지막으로, 애플리케이션별 오류를 처리하기 위해 사용자 정의 예외를 생성하고 발생시키는 연습을 통해 코드를 더 읽기 쉽고 유지보수하기 쉽게 만들었습니다.