Data/Python

[Python] 파이썬 오류 예외 처리 - try, except, finally

재은초 2023. 6. 17. 22:44
반응형

파이썬 오류 예외 처리란?

  • 파이썬은 try, except 등을 이용해서 오류를 무시하거나 별도 처리할 수 있게 해준다.
  • 파이썬의 모든 예외 클래스들은 Exception 클래스를 상속받아서 정의되는 객체

 

오류 발생 예시들

  • SyntaxError(구문 오류): 오타 쳤을 때
  • FileNotFoundError: 디렉터리 안에 없는 파일을 열려고 시도했을 때 발생하는 오류
  • ZeroDivisionError: 4등의 숫자로 0을 나누려고 할 때
  • IndexError: a는 [1, 2, 3]이라는 리스트를 가지고 있는데 a[4]는 a 리스트에서 얻을 수 없는 값일 때

https://python.bakyeono.net/chapter-9-4.html

 

오류 예외 처리 기법

① try .. except문

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

1. try, except만 쓰는 방법: 오류 종류에 상관없이 오류 발생시 except 블록 수행

try:
    ...
except:
    ...

 

2. 발생 오류만 포함한 except문: 발생한 오류가 except문 내 오류와 일치할 때만 except 블록 수행

try:
    ...
except 발생 오류:
    ...

3. 발생 오류와 오류 메시지 변수까지 포함한 except문: 두 번째 경우에서 오류 내용까지 알고 싶을 때 사용

try:
    ...
except 발생 오류 as 오류 메시지 변수:
    ...

# 예시
>>> try:                             # 4 나누기 0, ZeroDivisionError 발생
>>>    4 / 0        
>>> except ZeroDivisionError as e:   # except 블록이 실행 후 
>>>    print(e)                      # e 오류 메시지 출력
division by zero

② try .. finally문

  • finally절은 예외 발생 여부에 상관없이 항상 수행됨.
  • 보통 finally절은 사용한 리소스를 close해야 할 경우에 많이 사용된다.
>>> f = open('foo.txt', 'w')          # foo.txt라는 파일을 쓰기 모드로 연 후
>>> try:                              # try문이 수행된 후
>>>     # 무언가 수행                    
>>> finally:                          # finally절에서 예외 발생 여부에 상관없이
>>>     f.close()                     # 열린 파일 닫음

③ try .. except문으로 여러개의 오류 처리하기: 먼저 발생한 오류만 발생

# try문 내에서 여러개의 오류를 처리
try:
    ...
except 발생 오류1:
   ... 
except 발생 오류2:
   ...

# 예시 1
>>> 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             # 인덱싱 오류가 먼저 발생했으므로
                                    # 4/0의 오류는 발생하지 않음

# 예시 2
>>> try:
>>>     a = [1,2]
>>>     print(a[3])
>>>     4/0
>>> except (ZeroDivisionError, IndexError) as e:
>>>     print(e)
list index out of range            # 오류 메세지 출력

④ try .. else문: try문 수행중 오류가 발생하면 except절이 수행되고 오류가 없으면 else절이 수행

# try .. else
try:
    ...
except [발생 오류[as 오류 메시지 변수]]:
    ...
else:  # 오류가 없을 경우에만 수행된다.
    ...
    
# 예시
>>> try:
>>>     age=int(input('나이를 입력하세요: '))
>>> except:
>>>     print('입력이 정확하지 않습니다.')
>>> else:
>>>     if age <= 18:
>>>         print('미성년자는 출입금지입니다.')
>>>     else:
>>>         print('환영합니다.')

⑤ pass로 오류 회피하기: 특정 오류가 발생할 경우 그냥 통과시켜야 할 때

# try문 내에서 FileNotFoundError가 발생할 경우 pass를 사용하여 오류를 그냥 회피
>>> try:
>>>     f = open("나없는파일", 'r')
>>> except FileNotFoundError:
>>>     pass

 

⑥  raise로 오류 일부러 발생시키기

  • NotImplementedError는 파이썬 내장 오류로, 꼭 작성해야 하는 부분이 구현되지 않았을 경우 일부러 오류를 발생시키고자 사용
# Bird 클래스 상속받는 자식 클래스 Eagle에서 fly 함수 구현
>>> class Bird:
>>>     def fly(self):                 
>>>         raise NotImplementedError  # 구현되지 않았을 경우 일부러 오류 발생

>>> class Eagle(Bird):                 # Bird 클래스 상속
>>>     pass                          
>>> eagle = Eagle()                    # Eagle 클래스 객체 생성
>>> eagle.fly()                        # Bird 클래스의 fly 함수 호출
Traceback (most recent call last):     # Bird의 raise문에 의해
  File "...", line 33, in <module>     # NotImplementedError가 발생
    eagle.fly()
  File "...", line 26, in fly
    raise NotImplementedError
NotImplementedError

# NotImplementedError가 발생되지 않게 하려면
>>> class Eagle(Bird):                # Eagle 클래스에 fly 함수 구현 필요
>>>     def fly(self):
>>>         print("very fast")
>>> eagle = Eagle()
>>> eagle.fly()
very fast                            # 오류 없이 문장 출력

⑦ 예외 만들기

  • 예외는 파이썬 내장 클래스인 Exception클래스를 상속하여 만들 수 있으며, 프로그램 수행 도중 특수한 경우에만 예외처리를 하기 위해서 종종 예외를 만들어서 사용.
# 예외 만들기 기본 구조
class MyError(Exception):
    pass
# 예시
>>> def say_nick(nick):
>>>     if nick == '바보':
>>>         raise MyError()
>>>     print(nick)
>>>
>>> say_nick("천사")
천사
>>> say_nick("바보")                      # 에러 발생
Traceback (most recent call last):
  File "...", line 11, in <module>
    say_nick("바보")
  File "...", line 7, in say_nick
    raise MyError()
__main__.MyError

# MyError 예외처리
>>> try:                                # try 구문 실행
>>>     say_nick("천사")
>>>     say_nick("바보")
>>> except MyError:                     # try문 실행 중 해당 에러 발생시 수행
>>>     print("허용되지 않는 별명입니다.")
천사
허용되지 않는 별명입니다.

# MyError가 발생시 오류 메세지 보여주기
>>> class MyError(Exception):            # 오류 클래스에 __str__ 메써드 구현
>>>     def __str__(self):               # __str__ 메써드 오류메시지 출력 
>>>         return "허용되지 않는 별명입니다." 
>>> try:
>>>     say_nick("천사")
>>>     say_nick("바보")
>>> except MyError as e:
>>>     print(e)

 

Reference

반응형