Python의 예외처리는 코드 실행 중 발생할 수 있는 오류를 관리하고 처리하는 데 중요한 역할을 합니다. 예외처리를 잘 이해하면 프로그램의 안정성을 높이고, 예기치 않은 상황에서도 프로그램이 올바르게 작동하도록 할 수 있습니다. 이 글에서는 Python의 예외처리에 대한 기초부터 고급 활용까지 자세히 설명하겠습니다.
예외처리는 프로그램 실행 중 발생할 수 있는 오류나 예외 상황을 처리하는 방법입니다. Python에서는 예외가 발생하면 프로그램의 기본 흐름이 중단되고, 예외가 발생한 위치에서 예외가 발생했음을 알리는 메시지를 출력합니다.
try-except 블록을 사용하여 예외를 처리할 수 있습니다. try 블록에는 예외가 발생할 가능성이 있는 코드를 작성하고, except 블록에는 예외 발생 시 실행할 코드를 작성합니다.
try:
# 예외가 발생할 가능성이 있는 코드
result = 10 / 0
except ZeroDivisionError:
# 예외가 발생했을 때 실행할 코드
print("0으로 나눌 수 없습니다.")
출력:
0으로 나눌 수 없습니다.
except 블록을 여러 개 사용하여 다양한 예외를 처리할 수 있습니다.
try:
result = 10 / 0
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
except ValueError:
print("값 오류가 발생했습니다.")
모든 예외를 포괄적으로 처리하려면 Exception 클래스를 사용합니다.
try:
result = 10 / 0
except Exception as e:
print(f"예외가 발생했습니다: {e}")
출력:
예외가 발생했습니다: division by zero
raise 키워드를 사용하여 예외를 발생시킬 수 있습니다. 이는 사용자 정의 조건에서 예외를 발생시키는 데 유용합니다.
def check_value(value):
if value < 0:
raise ValueError("값은 0보다 커야 합니다.")
return value
try:
check_value(-1)
except ValueError as e:
print(e)
출력:
값은 0보다 커야 합니다.
raise 키워드를 사용하여 예외를 다시 발생시킬 수 있습니다. 이를 통해 기존 예외 정보를 유지하면서 새로운 예외를 발생시킬 수 있습니다.
try:
try:
result = 10 / 0
except ZeroDivisionError as e:
raise ValueError("값 오류가 발생했습니다.") from e
except ValueError as e:
print(f"새로운 예외: {e}")
print(f"원래 예외: {e.__cause__}")
출력:
새로운 예외: 값 오류가 발생했습니다.
원래 예외: division by zero
try 블록에서 예외가 발생하지 않은 경우 실행할 코드를 else 블록에 작성합니다.
try:
result = 10 / 2
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
else:
print(f"결과는 {result}입니다.")
출력:
결과는 5.0입니다.
finally 블록은 예외 발생 여부에 관계없이 항상 실행되는 코드를 작성합니다. 자원 정리 및 해제에 유용합니다.
try:
result = 10 / 0
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
finally:
print("예외 처리 완료.")
출력:
0으로 나눌 수 없습니다.
예외 처리 완료.
finally 블록은 파일이나 네트워크 연결과 같은 자원을 정리할 때 유용합니다.
try:
file = open("example.txt", "r")
content = file.read()
except FileNotFoundError:
print("파일을 찾을 수 없습니다.")
finally:
file.close()
print("파일을 닫았습니다.")
출력:
파일을 찾을 수 없습니다.
파일을 닫았습니다.
with 문은 자원을 할당하고 해제하는 과정을 자동으로 처리합니다. 파일 작업에서 자주 사용됩니다.
try:
with open('non_existent_file.txt', 'r') as file:
content = file.read()
except FileNotFoundError:
print("파일을 찾을 수 없습니다.")
출력:
파일을 찾을 수 없습니다.
with 문을 사용하면 파일을 열고 닫는 과정을 자동으로 처리할 수 있어 코드가 더 간결해집니다.
try:
with open("example.txt", "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print("파일을 찾을 수 없습니다.")
출력:
(파일 내용 출력 혹은 파일이 없을 때 "파일을 찾을 수 없습니다.")
with 문을 사용하려면 객체가 __enter__와 __exit__ 메서드를 구현해야 합니다. 이를 통해 사용자 정의 컨텍스트 매니저를 만들 수 있습니다.
class CustomContext:
def __enter__(self):
print("리소스를 획득합니다.")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("리소스를 해제합니다.")
with CustomContext() as context:
print("리소스를 사용하는 중입니다.")
출력:
리소스를 획득합니다.
리소스를 사용하는 중입니다.
리소스를 해제합니다.
기본 제공 예외 클래스 외에 사용자 정의 예외 클래스를 정의할 수 있습니다.
class CustomError(Exception):
pass
def check_value(value):
if value < 0:
raise CustomError("값은 0보다 커야 합니다.")
return value
try:
check_value(-1)
except CustomError as e:
print(e)
출력:
값은 0보다 커야 합니다.
try-except 블록으로 처리Exception 클래스를 상속받아 처리else와 finally 블록을 사용하여 추가적인 예외 처리 가능try-catch 블록으로 처리Throwable 클래스를 상속받아 처리finally 블록을 사용하여 자원 해제 가능Java 예제:
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
} finally {
System.out.println("예외 처리 완료.");
}
출력:
0으로 나눌 수 없습니다.
예외 처리 완료.
finally 블록이나 with 문을 사용하여 자원 해제를 자동으로 처리할 수 있습니다.데이터베이스 연결과 같은 자원 관리는 예외처리를 통해 안정적으로 처리할 수 있습니다.
import sqlite3
def connect_to_db(db_name):
try:
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
cursor.execute("SELECT * FROM non_existent_table")
except sqlite3.DatabaseError as
e:
print(f"데이터베이스 오류: {e}")
finally:
if conn:
conn.close()
# 사용 예시
connect_to_db('example.db')
출력:
데이터베이스 오류: no such table: non_existent_table
Python의 예외처리는 프로그램의 안정성과 유지보수성을 높이는 데 중요한 역할을 합니다. 기초적인
try-except구문부터 고급 기능인else,finally, 사용자 정의 예외까지 다양한 예외처리 방법을 이해하고 활용하면 더 견고하고 안정적인 코드를 작성할 수 있습니다.