본문 바로가기
Python/python

파이썬의 예외 처리 try-except 구문 이해하기

by 노마드 산코디 2023. 10. 28.
728x90

안녕하세요. 오늘은 파이썬 프로그래밍에서 코드의 안정성을 높이고 예외 상황을 처리하는 핵심적인 기능 중 하나인 '예외 처리'에 대해 알아보려고 합니다. 이 글에서는 파이썬의 try/except 구문을 중심으로 예외 처리의 기본 개념부터 고급 패턴까지 자세하게 살펴보겠습니다. 예외 처리는 파이썬 프로그램을 더 견고하고 오류를 처리하는 효과적인 방법 중 하나로, 이를 통해 더 효율적인 코드를 작성하는 방법을 배워보도록 하겠습니다.

 

 

 

 


1. 예외 처리의 기본 개념

예외 처리란 프로그램 실행 중에 예기치 않은 상황이 발생했을 때, 이러한 상황을 graceful하게 처리하는 프로그래밍 기술입니다. 파이썬에서 예외 처리는 코드의 안정성을 높이고 오류를 다루는 핵심적인 부분 중 하나입니다.

  • 예외 (Exception)
    예외란 프로그램 실행 중에 발생한 오류나 예기치 않은 상황을 가리킵니다. 이러한 예외는 여러 종류가 있으며, 각각 다른 상황에서 발생합니다.


  • try/except 구문
    try와 except 키워드를 사용하여 예외 처리를 정의합니다. try 블록 안에는 예외가 발생할 가능성이 있는 코드를 작성하고, except 블록 안에는 예외가 발생했을 때 실행할 코드를 작성합니다.


  • 예외 처리의 흐름
    예외가 발생하면 프로그램은 try 블록을 실행하다가 예외가 발생하면 해당 예외에 대응하는 except 블록으로 이동합니다. 이러한 동작은 예외가 처리될 때까지 계속됩니다.


  • 다양한 예외 처리
    여러 예외 유형을 처리하기 위해 except 블록은 예외의 종류를 지정할 수 있습니다. 예를 들어, ZeroDivisionError와 같은 특정 예외를 처리할 수 있습니다.


  • finally 블록
    finally 블록은 예외 처리 구문에서 선택적으로 사용됩니다. 이 블록은 예외가 발생하든 말든 항상 실행되는 코드를 포함하고 있습니다. 주로 리소스의 정리나 마무리 작업에 사용됩니다.


  • 예외 발생
    예외를 발생시키기 위해서는 raise 키워드를 사용합니다. 이를 통해 사용자 정의 예외를 만들거나 특정 예외를 발생시킬 수 있습니다.



예시 코드

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except ZeroDivisionError:
    # 예외 처리 코드
    print("0으로 나눌 수 없습니다.")
finally:
    # 항상 실행되는 코드
    print("예외 처리 완료")

# 출력:
# 0으로 나눌 수 없습니다.
# 예외 처리 완료




이처럼 예외 처리를 통해 예기치 않은 오류 상황에서도 프로그램을 안정적으로 유지하고, 오류 메시지를 사용자에게 적절하게 전달할 수 있습니다.

 

 

 

 


2. except 구문의 다양한 사용 방법



1. 특정 예외 처리 (Specific Exception Handling)
특정 예외 타입을 지정하여 해당 예외가 발생했을 때만 처리할 수 있습니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except ZeroDivisionError:
    # ZeroDivisionError 예외 처리 코드
    print("0으로 나눌 수 없습니다.")




2. 여러 예외 처리 (Multiple Exception Handling)
여러 예외 타입을 동시에 처리할 수 있습니다.

try:
    # 예외가 발생할 수 있는 코드
    num = int("abc")
    result = 10 / 0
except (ValueError, ZeroDivisionError):
    # ValueError 또는 ZeroDivisionError 예외 처리 코드
    print("값 오류 또는 0으로 나눌 수 없습니다.")




3. 예외 객체 사용
예외 객체를 활용하여 예외의 정보를 얻을 수 있습니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except ZeroDivisionError as e:
    # ZeroDivisionError 예외 처리 코드
    print(f"예외 발생: {e}")




4. 예외 타입 검사 및 다시 발생 (Re-Raising Exceptions)
예외를 처리한 후 다시 발생시키는 것이 가능합니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except ZeroDivisionError:
    # 예외 처리 코드
    print("0으로 나눌 수 없습니다.")
    raise  # 현재 예외를 다시 발생시킴




5. 기본 예외 처리 (Generic Exception Handling)
모든 예외를 하나의 except 블록에서 처리할 수 있습니다. 이 경우, 어떤 예외인지 명확하게 알 수 없으므로 주의해야 합니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except:
    # 모든 예외에 대한 처리 코드
    print("예외 발생")




6. finally 블록
try 블록에서 예외가 발생하든 발생하지 않든 항상 실행되는 코드 블록입니다. 주로 리소스 정리나 마무리 작업에 사용됩니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except ZeroDivisionError:
    # ZeroDivisionError 예외 처리 코드
    print("0으로 나눌 수 없습니다.")
finally:
    # 항상 실행되는 코드
    print("예외 처리 완료")




except 구문을 적절하게 활용하여 예외 처리를 세밀하게 조정할 수 있습니다. 예외 타입을 명확히 지정하고 예외 정보를 활용하면 디버깅 및 예외 처리를 더 효율적으로 수행할 수 있습니다.

 

 

 




3. else와 finally 블록



1. else 블록
try 블록의 코드가 예외를 발생시키지 않으면 else 블록이 실행됩니다. 즉, 예외가 발생하지 않았을 때 수행할 코드를 작성합니다. else 블록은 선택적으로 사용할 수 있습니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 2
except ZeroDivisionError:
    # ZeroDivisionError 예외 처리 코드
    print("0으로 나눌 수 없습니다.")
else:
    # 예외가 발생하지 않았을 때 실행될 코드
    print("계산 완료:", result)




2. finally 블록
finally 블록은 try 블록의 코드가 예외 발생 여부와 상관없이 항상 실행됩니다. 이 블록은 주로 리소스 정리나 마무리 작업에 사용됩니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except ZeroDivisionError:
    # ZeroDivisionError 예외 처리 코드
    print("0으로 나눌 수 없습니다.")
finally:
    # 항상 실행되는 코드
    print("예외 처리 완료")




이러한 블록들을 함께 사용하여 예외 처리를 더욱 유연하게 관리하고, 예외가 발생하더라도 필요한 작업을 수행할 수 있습니다. 이 중 else와 finally는 선택적으로 사용할 수 있으며, 필요에 따라 코드의 구조를 조정하여 사용하면 됩니다.

 








4. 예외처리와 코드 디버깅



예외 처리 (Exception Handling)

1. try/except 블록 사용
예외가 발생할 수 있는 코드를 try 블록 안에 넣고, 예외가 발생하면 except 블록에서 처리합니다.

try:
    # 예외가 발생할 수 있는 코드
    result = 10 / 0
except ZeroDivisionError:
    # ZeroDivisionError 예외 처리 코드
    print("0으로 나눌 수 없습니다.")



2. 여러 예외 처리
다양한 예외 타입을 처리하려면 여러 except 블록을 사용할 수 있습니다.

try:
    value = int(input("정수를 입력하세요: "))
    result = 10 / value
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")
except ValueError:
    print("올바른 정수를 입력하세요.")



3. else 블록 사용
try 블록의 코드가 예외를 발생시키지 않으면 else 블록이 실행됩니다.

try:
    result = 10 / 2
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")
else:
    print("계산 완료:", result)



4. finally 블록 사용
finally 블록은 예외 발생 여부와 상관없이 항상 실행되는 블록으로 주로 리소스 정리에 사용됩니다.

try:
    file = open("example.txt", "r")
    data = file.read()
except FileNotFoundError:
    print("파일을 찾을 수 없습니다.")
finally:
    file.close()





코드 디버깅 (Debugging)

1. print 문 사용
가장 간단한 디버깅 방법으로 코드 실행 중간에 print 문을 추가하여 변수의 값을 출력하고 코드의 흐름을 추적합니다.

x = 10
print("변수 x의 값:", x)



2. pdb 모듈 사용
파이썬 내장 디버거 모듈인 pdb를 사용하여 코드를 중지하고 단계별로 실행하거나 변수 값을 확인할 수 있습니다.

import pdb

def divide(a, b):
    result = a / b
    return result

pdb.set_trace()  # 디버거 활성화
result = divide(10, 0)



3. IDE나 디버깅 도구 사용
파이썬을 개발하는 통합 개발 환경(IDE) 또는 디버깅 도구를 사용하여 코드를 디버깅할 수 있습니다. 예를 들어, Visual Studio Code, PyCharm 등의 IDE를 사용하면 더 편리하게 디버깅할 수 있습니다.


4. 예외 추적 (Traceback)
예외가 발생하면 파이썬은 예외 발생 지점부터 호출 스택을 표시하여 문제를 해결하는 데 도움을 줍니다. 발생한 예외의 타입과 위치를 찾아서 수정합니다.



디버깅은 코드를 개선하고 문제를 해결하는 데 중요한 역할을 합니다. 디버깅 스킬을 연마하면 코드 작성 과정에서 빠르게 문제를 해결할 수 있습니다.

 

 





5. 예외처리시 주의사항



1. 너무 넓은 예외 처리 피하기
가능한 구체적인 예외 타입을 처리하고, except Exception 등으로 모든 예외를 처리하는 것을 피해야 합니다. 너무 넓은 예외 처리는 디버깅을 어렵게 만들 수 있습니다.


2. 의미 있는 예외 메시지 사용
예외를 발생시킬 때, 명확하고 의미 있는 메시지를 함께 출력하면 디버깅과 문제 해결이 용이해집니다.

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print("0으로 나눌 수 없습니다:", e)



3. 예외 무시하지 않기
발생한 예외를 무시하지 말고 적절한 대응을 해야 합니다. 무시된 예외는 문제를 찾기 어렵게 만들 수 있습니다.


4. 적절한 예외 처리 위치 선택
예외 처리는 예외가 발생하는 가장 가까운 위치에 두는 것이 좋습니다. 너무 먼 부분에서 처리하면 디버깅이 어려워질 수 있습니다.


5. 예외 타입 순서 중요
여러 예외 타입을 처리할 때, 가장 구체적인 예외부터 처리하고, 보다 일반적인 예외는 나중에 처리해야 합니다. 그렇지 않으면 구체적인 예외 처리 코드가 실행되지 않을 수 있습니다.

try:
    # 코드
except SpecificException:
    # 구체적인 예외 처리
except GeneralException:
    # 일반적인 예외 처리



6. 예외 발생 시 리소스 정리
파일이나 네트워크 연결과 같은 리소스를 사용하는 경우, finally 블록에서 리소스 정리를 수행하는 것이 좋습니다.

try:
    file = open("example.txt", "r")
    # 파일 읽기
except FileNotFoundError as e:
    print("파일을 찾을 수 없습니다:", e)
finally:
    file.close()  # 파일 항상 닫기



7. 예외 발생하지 않는 상황에 대한 예외 처리 피하기
예외가 예상되지 않는 상황에서 발생하는 예외 처리는 피하는 것이 좋습니다. 코드 논리적인 오류를 수정해야 합니다.



8. 감싸기 패턴 사용
함수나 메서드에서 예외를 처리할 때, 해당 예외를 감싸고 더 구체적인 예외를 던지는 것이 좋습니다. 이렇게 하면 예외를 발생시킨 위치와 처리 위치가 분리되어 디버깅이 쉬워집니다.

def divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError as e:
        raise ValueError("0으로 나눌 수 없습니다.") from e
    return result



9. 제3자 라이브러리 예외 처리
제3자 라이브러리를 사용할 때, 해당 라이브러리에서 발생하는 예외를 적절하게 처리해야 합니다. 라이브러리 문서를 참고하고 관련 예외 처리를 수행하세요.



예외 처리는 코드의 안정성을 높이고 예기치 않은 문제에 대처하는 중요한 부분입니다. 따라서 적절한 예외 처리 스타일과 패턴을 사용하여 코드를 작성하는 것이 중요합니다.

 

 

 




최종 정리

오늘은 파이썬의 예외처리에 대한 내용을 주제로 정리해 보았습니다. 파이썬 예외 처리는 코드의 안정성을 높이고 예기치 않은 문제에 대처하는 중요한 부분입니다. 올바른 예외 처리 스타일과 패턴을 사용하여 코드를 작성하면 더욱 견고하고 안정적인 프로그램을 개발할 수 있습니다. 

감사합니다.

 

 

 

 

728x90
반응형