Python 예외 처리

배추·2025년 11월 23일

🐍 Python

목록 보기
16/19

Python의 오류를 처리하는 방법에 대해 알아봅니다.


▶︎오류는 언제 발생하는가?

: 파이썬은 오류가 발생하면 프로그램을 중단하고 오류 메시지를 보여 준다.

  • 존재하지 않는 파일을 사용하려고 시도했을 때 발생하는 오류.
>>> f = open("나없는파일", 'r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '나없는파일'
  • 0으로 다른 숫자를 나누는 경우를 생각해 보자. 이 역시 자주 발생하는 오류.
>>> 4 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
  • IndexError 오류.
>>> a = [1, 2, 3]
>>> a[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

▶︎오류 예외 처리 기법

try:
    ... # 오류가 발생할 수 있는 구문
except 발생오류 as 오류변수:
    ... # 오류 발생
else:
    ... # 오류 발생하지 않음
finally:
	... # 무조건 마지막에 실행

try-except 문

try:
    ...
except [발생오류 [as 오류변수]]:
    ...
  • try 블록 수행 중 오류가 발생하면 except 블록이 수행된다.
  • try 블록에서 오류가 발생하지 않는다면 except 블록은 수행되지 않는다.
  • []: 괄호 안의 내용을 생략할 수 있다는 관례적인 표기법.

try-except만 쓰는 방법

try:
    ...
except:
    ...
  • 오류의 종류에 상관없이 오류가 발생하면 except 블록을 수행한다.

발생 오류만 포함한 except 문

try:
    ...
except 발생오류:
    ...
  • 오류가 발생했을 때 except 문에 미리 정해 놓은 오류와 동일한 오류일 경우에만 except 블록을 수행한다.

발생 오류와 오류 변수까지 포함한 except 문

try:
    ...
except 발생오류 as 오류변수:
    ...
  • 두 번째 경우에서 오류의 내용까지 알고 싶을 때 사용하는 방법.
  • # try_except.py
    try:
        4 / 0
    except ZeroDivisionError as e:
        print(e) # division by zero
    • 4를 0으로 나누려고 하면 ZeroDivisionError가 발생하여 except 블록이 실행되고 오류 변수 e에 담기는 오류 메시지를 출력할 수 있다.

try-finally 문

  • finally 절은 try 문 수행 도중 예외 발생 여부에 상관없이 항상 수행된다.
  • 보통 finally 절은 사용한 리소스를 close해야 할 때 많이 사용한다.
# try_finally.py
try:
    f = open('foo.txt', 'w')
    # 무언가를 수행한다.

    (... 생략 ...)

finally:
    f.close()  # 중간에 오류가 발생하더라도 무조건 실행된다.

여러 개의 오류 처리하기

  • try 문 안에서 여러 개의 오류를 처리하려면 except를 계속 사용한다.
try:
    ...
except 발생오류1:
   ... 
except 발생오류2:
   ...
  • 예) 0으로 나누는 오류와 인덱싱 오류 처리

    # many_error.py
    try:
        a = [1,2]
        print(a[3])
        4/0
    except ZeroDivisionError as e:
        print(e)
    except IndexError as e:
        print(e)
    
    # list index out of range
  • 2개 이상의 오류를 동일하게 처리하기 위해서는 괄호를 사용하여 함께 묶어 처리한다.

    try:
        a = [1,2]
        print(a[3])
        4/0
    except (ZeroDivisionError, IndexError) as e:
        print(e)

try-else 문

try:
    ...
except [발생오류 [as 오류변수]]:
    ...
else:  # 오류가 없을 경우에만 수행
    ...
  • try 문 수행 중 오류가 발생하면 except 절, 오류가 발생하지 않으면 else 절이 수행된다.

▶︎오류 회피하기

continue

  • 특정 오류가 발생할 경우 그냥 통과시켜야 할 때.
# process_scores.py
students = ["김철수", "이영희", "박민수", "최유진"]

for student in students:
    try:
        with open(f"{student}_성적.txt", 'r') as f:
            score = f.read()
            print(f"{student}의 성적: {score}")
    except FileNotFoundError:
        print(f"{student}의 성적 파일이 없습니다. 건너뜁니다.")
        continue  # 다음 학생으로 넘어감

pass

  • 오류를 완전히 무시하고 싶을 때.
  • pass는 신중하게 사용해야 한다. 중요한 오류까지 무시하면 나중에 더 큰 문제가 될 수 있다.
# error_pass.py
try:
    # 설정 파일을 읽으려 시도
    f = open("설정파일.txt", 'r')
    config = f.read()
    f.close()
except FileNotFoundError:
    pass  # 설정 파일이 없어도 계속 진행

# 프로그램의 주요 기능은 계속 수행
print("프로그램이 정상적으로 실행됩니다.")

▶︎오류 일부러 발생시키기

  • raise 명령어: 오류를 강제로 발생.
# error_raise.py
class Bird:
    def fly(self):
        raise NotImplementedError
class Eagle(Bird):
    pass

eagle = Eagle()
eagle.fly() # NotImplementedError

# => Bird 클래스를 상속받는 자식 클래스는 반드시 fly 함수를 구현해야 한다
  • NotImplementedError: 파이썬에 이미 정의되어 있는 오류. 꼭 작성해야 하는 부분이 구현되지 않았을 경우 일부러 오류를 발생시키기 위해 사용.

▶︎예외 만들기

  • 특수한 경우에만 예외 처리를 하려고 종종 예외를 만들어서 사용한다.
  • 예외는 파이썬 내장 클래스인 Exception 클래스를 상속하여 만들 수 있다.
class MyError(Exception):
    pass
  • raise로 MyError 발생.
def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)
    
say_nick("천사") # 천사
say_nick("바보") # MyError
  • 예외 처리 기법을 사용하여 MyError 발생을 예외 처리.
try:
    say_nick("천사")
    say_nick("바보")
except MyError:
    print("허용되지 않는 별명입니다.")

# 천사
# 허용되지 않는 별명입니다.

__str__

  • 오류 메시지를 출력했을 때 오류 메시지가 보이게 하려면 오류 클래스에 __str__ 메서드를 구현해야 한다.
  • __str__ 메서드: print(e)처럼 오류 메시지를 print 문으로 출력할 경우에 호출되는 메서드.
class MyError(Exception):
    def __str__(self):
        return "허용되지 않는 별명입니다."
try:
    say_nick("천사")
    say_nick("바보")
except MyError as e:
    print(e)
    
# 천사
# 허용되지 않는 별명입니다.
profile
난 🥬

0개의 댓글