目次
1. Python의 예외란 무엇인가
Python의 예외는 프로그램 실행 중에 발생하는 오류의 일종입니다. 일반적으로 프로그램은 위에서 아래로 코드를 실행하지만, 특정 상황에서 오류가 발생하면 해당 부분의 코드 실행이 중단되고 예외가 발생합니다. 예를 들어, 0으로 나눗셈을 시도하면ZeroDivisionError가 발생하고, 존재하지 않는 리스트의 인덱스에 접근하려고 하면IndexError가 발생합니다.1.1 흔히 발생하는 예외 종류
Python에는 많은 내장 예외가 존재합니다. 몇 가지 일반적인 예를 아래에 보여드립니다.ValueError: 함수가 적절하지 않은 값을 받았을 경우TypeError: 연산 또는 함수가 부적절한 데이터 타입에 대해 수행된 경우IndexError: 시퀀스(리스트 등)의 범위를 벗어난 인덱스에 접근한 경우ZeroDivisionError: 0으로 나눗셈을 시도한 경우
2. try와 except에 의한 기본적인 예외 처리
Python에서는 try와 except를 사용하여 예외 처리를 수행합니다. 이를 통해 프로그램이 오류로 중단되는 것을 방지하고, 오류가 발생한 경우에도 프로그램의 다른 부분을 계속 실행할 수 있습니다.2.1 기본 구문
try 블록 안에 오류가 발생할 가능성이 있는 코드를 배치하고, except 블록 안에 그 오류가 발생했을 때 실행되는 코드를 작성합니다.try:
result = 10 / 0
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")이 예에서는 ZeroDivisionError가 발생하면 except 블록이 실행되어 “0으로 나눌 수 없습니다.”가 출력됩니다.2.2 여러 개의 except 블록
여러 개의 다른 예외를 처리하고 싶을 경우, 여러 개의 except 블록을 사용할 수 있습니다. 예를 들어, NameError나 TypeError와 같은 서로 다른 오류에 대해 각각 다른 처리를 할 수 있습니다.try:
print(a)
except NameError:
print('변수 a의 값이 정의되어 있지 않습니다.')
except TypeError:
print('잘못된 타입이 사용되었습니다.')이 코드에서는 a가 정의되지 않은 경우 NameError가 발생하고, 해당 메시지가 표시됩니다.3. 여러 예외를 한 번에 처리하는 방법
프로그램에서 여러 종류의 서로 다른 예외가 발생할 가능성이 있는 경우, 이를 하나의except 블록으로 한 번에 처리할 수 있습니다.3.1 여러 예외를 하나의 except 블록으로 처리
다음과 같이, except 블록에서 여러 예외를 튜플로 지정할 수 있습니다.try:
num = int(input("숫자를 입력해주세요: "))
result = 10 / num
except (ValueError, ZeroDivisionError):
print("잘못된 입력이 있었거나, 0으로 나눗셈을 시도했습니다.")이 예에서는 사용자가 잘못된 값을 입력했거나 0을 입력해 나눗셈을 시도한 경우, 이를 한 번에 처리하고 “잘못된 입력이 발생했거나, 0으로 나눗셈을 시도했습니다.” 라고 출력합니다.3.2 부모 클래스를 사용하여 예외를 한 번에 처리
Exception 클래스는 대부분의 내장 예외의 부모 클래스입니다. 모든 예외를 잡고 싶을 경우 이 클래스를 사용할 수 있습니다. 다만, 이 방법은 매우 광범위하므로 사용에 주의가 필요합니다.try:
# 오류가 발생할 가능성이 있는 코드
except Exception as e:
print("오류가 발생했습니다:", e)이 방법에서는 어떤 예외가 발생하더라도 잡히고 메시지가 표시됩니다. 다만, 가능한 한 특정 예외를 처리하도록 설계하는 것이 권장됩니다.
4. 예외를 발생시키기 (raise)
프로그램 실행 중에 특정 조건이 충족되지 않을 경우 수동으로 예외를 발생시킬 수 있습니다. 이를 위해서는 raise 문을 사용합니다.4.1 raise문의 사용법
다음 예에서는 음수 값이 전달될 경우 ValueError를 발생시킵니다.def check_value(value):
if value < 0:
raise ValueError("음수 값은 허용되지 않습니다.")
return value
try:
result = check_value(-1)
except ValueError as e:
print(e)이 예에서는 -1이라는 음수 값이 check_value 함수에 전달되므로 ValueError가 발생하고, “음수 값은 허용되지 않습니다.”라는 메시지가 표시됩니다.4.2 raise의 응용
raise 문은 커스텀 예외 클래스를 정의할 때도 사용할 수 있습니다. 독자적인 예외를 만들고 특정 조건에서 이를 발생시킴으로써 프로그램의 오류 처리를 보다 유연하게 할 수 있습니다.5. 예외 정보 가져오기
예외가 발생했을 때, 그 상세 정보를 가져옴으로써 문제 진단 및 디버깅을 쉽게 할 수 있습니다.except 블록에서 as 절을 사용하면 예외 객체를 가져올 수 있습니다.5.1 as 절 사용법
다음 예에서는 예외 객체를 e 로 가져와서 그 메시지를 표시합니다.try:
result = 10 / 0
except ZeroDivisionError as e:
print("오류가 발생했습니다:", e)이 코드에서는 ZeroDivisionError가 발생하면, 「오류가 발생했습니다: division by zero」라는 메시지가 표시됩니다. 예외 객체에는 예외 유형 및 오류 메시지와 같은 상세 정보가 포함되어 있습니다.5.2 예외 객체 활용
예외 객체는 오류 메시지 표시뿐만 아니라 로그 기록이나 특정 오류에 대한 추가 처리를 수행하는 데에도 사용할 수 있습니다. 예를 들어, 로그 파일에 오류 메시지를 기록하여 나중에 디버깅에 활용할 수 있습니다.6. 예외 처리 베스트 프랙티스
효과적인 예외 처리는 프로그램의 견고함과 신뢰성을 향상시킵니다. 아래에 Python에서의 예외 처리 베스트 프랙티스를 몇 가지 소개합니다.6.1 특정 예외를 잡기
가능한 한, 특정 예외를 잡도록 합시다. 광범위한Exception을 잡는 것이 아니라,ValueError나TypeError 등 예상되는 특정 예외를 잡음으로써 오류 처리를 보다 명확하고 의도적으로 만들 수 있습니다.6.2 예외를 로그에 기록하기
오류 메시지를 로그에 기록하면 나중에 문제 원인을 파악하기 쉬워집니다. 특히 대규모 프로그램이나 시스템에서는 예외가 발생했을 때의 정보를 기록하는 것이 중요합니다.6.3 우아한 저하
예외가 발생해도 프로그램이 완전히 크래시되지 않도록, 우아한 저하(graceful degradation)를 설계하는 것이 중요합니다. 예를 들어, 사용자에게 이해하기 쉬운 오류 메시지를 표시하거나 대체 동작을 실행함으로써 프로그램의 신뢰성을 향상시킬 수 있습니다.6.4 중복된 예외 처리 피하기
모든 예외를 잡고 아무 것도 하지 않은 채 무시하는 것은 피합시다. 이는 디버깅을 어렵게 하고 프로그램의 예상치 못한 동작을 초래할 수 있습니다. 예외를 잡은 경우 최소한 오류 메시지를 기록하거나 적절한 처리를 하도록 합니다.6.5 finally 블록 활용
finally 블록은 예외 여부와 관계없이 반드시 실행되는 코드를 기술하는 데 사용됩니다. 예를 들어, 파일 닫기나 리소스 해제 등 반드시 실행해야 하는 처리를 여기서 기술합니다.try:
file = open("example.txt", "r")
# 파일을 읽는 처리
except FileNotFoundError:
print("파일을 찾을 수 없습니다.")
finally:
file.close()이 예에서는 파일 열기에 실패한 경우에도 finally 블록에서 확실히 파일을 닫습니다.7. 요약
Python의 예외 처리는 프로그램의 신뢰성을 높이고, 오류 발생 시 적절한 대응을 가능하게 하는 중요한 기술입니다.try와 except를 사용해 오류를 포착하고, raise로 커스텀 예외를 생성함으로써 코드의 유연성과 유지보수성을 향상시킬 수 있습니다.- 예외가 무엇인지 이해하고, 일반적인 예외 종류에 대해 배웠습니다.
try와except를 사용하여 기본적인 예외 처리를 수행하는 방법을 배웠습니다.- 여러 예외를 하나의
except블록으로 묶어 처리하는 방법을 살펴보았습니다. raise문을 사용해 예외를 발생시키는 방법과 그 응용에 대해 배웠습니다.- 예외 객체를 얻어 상세한 오류 정보를 확인하는 방법을 배웠습니다.
- 마지막으로, 예외 처리의 베스트 프랙티스에 대해 고민하고, 효과적인 오류 처리 설계에 대해 언급했습니다.




