오경석의 개발노트

Python_예외처리(try, except, else, finally) 본문

프로그래밍 언어/Python

Python_예외처리(try, except, else, finally)

OHSAYU 2022. 9. 23. 09:02

    프로그램을 만들다 보면 수없이 많은 오류를 만나게 된다. 프로그램 실행 중에 발생하는 오류를 예외(exception) 또는 런타임 오류(runtime error)라고 한다. 물론 오류가 발생하는 이유는 프로그램이 잘못 동작하는 것을 막기 위한 파이썬의 배려이다.

    하지만 때때로 이러한 오류를 무시하고 싶을 때도 있다. 오류가 나면 스크립트 실행이 중단되는데 이를 방지하거나(ex. 웹 크롤링 시 에러가 발생해도 계속 실행하고 이후에 에러가 발생한 부분만 다시 실행), 오류에 이름을 지정해줘서 보기 편하게 할 수 있다.

    프로그램이 안정적으로 구동될 수 있기 위해서는 예외 상황에 대한 처리를 잘해주어야 한다. 물론 조건문을 통해 예외상황을 처리해줄 수도 있지만 예외가 발생하는 상황을 예측하고 모두 조건문으로 처리하기란 쉽지 않다. 또한 프로그래밍의 구조적인 문제로 인하여 조건문만으로 처리 불가능한 예외 상황도 있다.

    이를 위해 파이썬은 try, except를 사용해서 예외적으로 오류를 처리할 수 있게 해 준다. 먼저 전체 구조를 살펴보자.

 

예외처리 구조

try:
    예외가 발생할 가능성이 있는 코드
except:
    예외 발생시 실행하는 코드
else:
    예외가 발생하지 않았을 때 실행하는 코드
finally:
    무조건 실행하는 코드

 

예외처리 실행과정

try, except

try:
    예외가 발생할 가능성이 있는 코드
except [발생 오류[as 오류 메시지 변수]]:
    예외 발생시 실행하는 코드
'try안에 있는 코드를 시도해보고, 예외가 발생하면 except문을 실행하라'

    오류 처리를 위한 try, except의 기본 구조이다. try 블록 실행 중 오류가 발생하면 except 블록이 수행된다. 하지만 try 블록에서 오류가 발생하지 않는다면 except 블록은 수행되지 않는다. except 구문을 보면 [] 기호를 사용하는데, 이 기호는 괄호 안의 내용을 생략할 수 있다는 관례 표기법이다. 즉, except 구문은 다음 3가지 방법으로 사용할 수 있다.

 

try, except 3가지 구조

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

# 2. 발생 오류만 포함한 except문 : 오류 발생시 except문에 미리 정해 놓은 오류 이름과 일치할 때만 except 블록 수행    
try:
    ...
except 발생 오류:
    ...
    
# 3. 발생 오류와 오류 메시지 변수까지 포함한 except문 : 두 번째 경우에서 오류 메시지의 내용까지 알고 싶을 때 사용
try:
    ...
except 발생 오류 as 오류 메시지 변수:
    ...

 

try, except 예시

try:
    4 / 0
except ZeroDivisionError as e:
    print(e)
>>>
division by zero

 

try, except 여러 개의 오류 처리하기

try문 안에서 여러 개의 오류를 처리하기 위해 다음 구문을 사용한다.

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

 

try, except 여러 개의 오류 처리하기 예시

try:
    a = [1,2]
    print(a[2])
    print(4/0)
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")
except IndexError:
    print("인덱싱 할 수 없습니다.")
>>>
인덱싱 할 수 없습니다.

    a는 2개의 요솟값을 가지고 있기 때문에 print(a[2])는 IndexError를 발생시키므로 "인덱싱할 수 없습니다."라는 문자열이 출력될 것이다. print(a[2])에서 인덱싱 오류가 먼저 발생해서 print(4/0)는 실행되지 않고 바로 except로 가기 때문에 ZeroDivisionError 오류 또한 출력되지 않았다.

    예외가 여러 개 발생하더라도 먼저 발생한 예외의 처리 코드만 실행된다(또는 예외 중에서 높은 계층의 예외부터 처리된다. 기반 클래스 > 파생 클래스 순). 참고로 모든 예외의 에러 메시지를 출력하고 싶다면 다음과 같이 except에 Exception을 지정하고 as 뒤에 변수를 넣으면 된다.

except Exception as e: # 모든 예외의 에러 메시지를 출력할 때는 Exception을 사용
    print(e)

 

예외 발생과 실행 구조

 

파이썬 예외 계층도

try except 오류 메시지 출력하기

try:
    a = [1,2]
    print(a[2])
    print(4/0)
except ZeroDivisionError as e:
    print(e)
except IndexError as e:
    print(e)
>>>
list index out of range

프로그램을 실행하면 "list index out of range" 오류 메시지가 출력될 것이다. 다음과 같이 ZeroDivisionError와 IndexError를 함께 처리할 수도 있다.

 

try except 2개 이상의 오류 메시지를 괄호로 묶어 함께 출력하기

try:
    a = [1,2]
    print(a[2])
    print(4/0)
except (ZeroDivisionError, IndexError) as e:
    print(e)
>>>
list index out of range

 

 

try문에 else절 사용하기

try:
    ...
except [발생 오류[as 오류 메시지 변수]]:
    ...
else: # 오류가 없을 경우에만 수행된다.
    ...

try문 수행 중 오류가 발생하면 except절이 수행되고 오류가 없으면 else절이 수행된다. 사실 else 없이 try 구문 안에 넣어도 문제가 없다. 각자 스타일에 따라 else 구문을 활용해도, 하지 않아도 된다.

 

try문에 else 절을 활용하는 간단한 예

try:
    age = int(input('나이를 입력하세요 : '))
except:
    print('입력이 정확하지 않습니다.')
else:
    if age <= 18:
        print('미성년자는 출입금지입니다.')
    else:
        print('환영합니다.')

만약 '나이를 입력하세요 : '라는 질문에 숫자가 아닌 다른 값을 입력하면 오류가 발생하여 '입력이 정확하지 않습니다.'라는 문장을 출력한다. 오류가 없을 경우에면 else절이 수행된다.

 

오류 회피하기

프로그래밍을 하다 보면 특정 오류가 발생할 경우 그냥 통과시켜야 할 때가 있다. 다음 예를 보자.

try:
    f = open('존재하지 않는 파일', 'r')
except FileNotFoundError:
    pass

try문 안에서 FileNotFoundError가 발생할 경우에 pass를 사용하여 오류를 그냥 회피하도록 작성한 예제이다.

 

raise로 예외 발생시키기

프로그래밍을 하다 보면 종종 오류를 일부러 발생시켜야 할 경우도 생긴다. 파이썬은 raise 명령어를 사용해 오류를 강제로 발생시킬 수 있다(에러 메시지도 첨부 가능). 

try:
    x = int(input("3의 배수를 입력하세요 : "))
    if x % 3 != 0:
        raise Exception("3의 배수가 아닙니다.")
    print(x)
except Exception as e:
    print(e)
>>>
3의 배수를 입력하세요 : 5
3의 배수가 아닙니다.

5는 3의 배수가 아니므로 raise Exception("3의 배수가 아닙니다.")로 예외를 발생시켰다. 그리고 raise로 예외를 발생시키면 raise 아래에 있는 코드는 실행되지 않고 바로 except로 넘어간다. 따라서 try의 print(x)는 실행되지 않는다.

※ 이 예제에서는 예외로 Exception을 사용했는데 다른 예외 이름으로 사용해도 상관없다.
예외를 새롭게 만들어주면 다른 코드 블록에서도 사용 가능하다.

 

 

assert로 예외 발생시키기

예외를 발생시키는 방법 중에는 assert를 사용하는 방법도 있다. assert는 지정된 조건식이 거짓일 때 AssertionError 예외를 발생시키며 조건식이 참이면 그냥 넘어간다. 보통 assert는 나와서는 안 되는 조건을 검사할 때 사용한다.

x = int(input('3의 배수를 입력하세요: '))
assert x % 3 == 0, '3의 배수가 아닙니다.'    # 3의 배수가 아니면 예외 발생, 3의 배수이면 그냥 넘어감
print(x)
>>>
3의 배수를 입력하세요: 5
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_59696/2393333499.py in <module>
      1 x = int(input('3의 배수를 입력하세요: '))
----> 2 assert x % 3 == 0, '3의 배수가 아닙니다.'    # 3의 배수가 아니면 예외 발생, 3의 배수이면 그냥 넘어감
      3 print(x)

AssertionError: 3의 배수가 아닙니다.

 

예외 만들기

프로그램 수행 도중 특수한 경우에만 예외 처리를 하기 위해서 종종 예외를 만들어서 사용한다. 직접 예외를 만들어 보자. 예외는 다음과 같이 파이썬 내장 클래스인 Exception 클래스를 상속하여 만들 수 있다.

class 예외이름(Exception):
    def __init__(self):
        super().__init__("에러메시지")

 

참고로 다음과 같이 Exception만 상속받고 pass를 넣어서 아무것도 구현하지 않아도 된다.

class 예외 이름(Exception):
    pass

 

예외 만들기 예시

class NotThreeMultifle(Exception):
    def __init__(self):
        super().__init__("3의 배수가 아닙니다.")
        
def three_multiple():
    try:
        x = int(input("3의 배수를 입력하세요 : "))
        if x % 3 != 0:
            raise NotThreeMultifle
        print(x)
    except Exception as e:
        print(e)
        
three_multiple()
>>>
3의 배수를 입력하세요 : 5
3의 배수가 아닙니다.

5를 입력하면 3의 배수가 아니므로 NotThreeMultipleError 예외가 발생한다.

 

finally

try문에는 finally절을 사용할 수 있다. finally절은 try문 수행 도중 예외 발생 여부에 상관없이 항상 수행된다. 보통 finally절은 사용한 리소스를 close해야 할 때 많이 사용된다.

 

finally 예시

f = open('test.txt', 'w')
try:
    f
finally:
    f.close()

test.txt 파일을 쓰기 모드로 연 후에 try문을 수행한 후 예외 발생 여부와 상관없이 finally절에서 f.close()로 열린 파일을 닫을 수 있다.

 

finally 예시2

try:
    age = int(input('나이를 입력하세요 : '))
except:
    print('입력이 정확하지 않습니다.')
else:
    if age <= 18:
        print('미성년자는 출입금지입니다.')
    else:
        print('환영합니다.')
finally:
    print('실행이 종료되었습니다.')
>>>
나이를 입력하세요 : 12
미성년자는 출입금지입니다.
실행이 종료되었습니다.
try:
    age = int(input('나이를 입력하세요 : '))
except:
    print('입력이 정확하지 않습니다.')
else:
    if age <= 18:
        print('미성년자는 출입금지입니다.')
    else:
        print('환영합니다.')
finally:
    print('실행이 종료되었습니다.')
>>>
나이를 입력하세요 : 20
환영합니다.
실행이 종료되었습니다.
※ try, except, else, finally안에서 만든 변수는 바깥에서도 사용할 수 있다.

    이처럼 finally는 예외가 발생하든 하지 않든 항상 실행된다. 기본적으로 예외처리를 하려면 try와 except는 무조건 필요하다. 예외가 발생하지 않는 상황에 뭔가를 처리해주려면 else가 필요할 것이고 예외가 발생하든 안 하든 상관없이 무조건 try 구문이 종료되고 실행되어야 하는 구문이 있다면 finally를 추가하면 된다.

 

 

출처 : https://devpouch.tistory.com/85

출처 : https://www.infoking.site/71

 

파이썬 예외처리 try, except문 문법과 사용방법은?!

코딩을 하다보면 예기치 못한 오류를 접하게 된다. 이러한 예외 케이스를 해결하고 오류를 수정하는데 많은 시간이 걸린다. 때로는 동일한 작업인데도 작업환경이나 상황에 따라 간혹 에러가

www.infoking.site

출처 : https://wikidocs.net/30

 

05-4 예외 처리

프로그램을 만들다 보면 수없이 많은 오류를 만나게 된다. 물론 오류가 발생하는 이유는 프로그램이 잘못 동작하는 것을 막기 위한 파이썬의 배려이다. 하지만 때때로 이러한 오류 ...

wikidocs.net

출처 : https://dojang.io/mod/page/view.php?id=2398 

 

파이썬 코딩 도장: 38.1 try except로 사용하기

Unit 38. 예외 처리 사용하기 예외(exception)란 코드를 실행하는 중에 발생한 에러를 뜻합니다. 다음과 같이 10을 어떤 값으로 나누는 함수 ten_div가 있을 때 인수에 따라 정상으로 동작하기도 하고 에

dojang.io

출처 : https://dojang.io/mod/page/view.php?id=2399 

 

파이썬 코딩 도장: 38.2 else와 finally 사용하기

이번에는 예외가 발생하지 않았을 때 코드를 실행하는 else를 사용해보겠습니다. 다음과 같이 else는 except 바로 다음에 와야 하며 except를 생략할 수 없습니다. try:     실행할 코드 except:     예

dojang.io

출처 : https://dojang.io/mod/page/view.php?id=2400 

 

파이썬 코딩 도장: 38.3 예외 발생시키기

지금까지 숫자를 0으로 나눴을 때 에러, 리스트의 범위를 벗어난 인덱스에 접근했을 때 에러 등 파이썬에서 정해진 예외만 처리했습니다. 이번에는 우리가 직접 예외를 발생시켜 보겠습니다. 예

dojang.io

출처 : https://dojang.io/mod/page/view.php?id=2401 

 

파이썬 코딩 도장: 38.4 예외 만들기

지금까지 파이썬에 내장된 예외를 처리했는데, 이번에는 예외를 직접 만들어서 발생시켜보겠습니다. 프로그래머가 직접 만든 예외를 사용자 정의 예외라고 합니다. ▼ 그림 38-4 내장된 예외와

dojang.io

출처 : https://devpouch.tistory.com/85

 

[Python] 파이썬 예외 처리 - try except else finally구문

프로그램 실행 중에 발생하는 오류를 예외(exception) 또는 런타임 오류(runtime error)라고 합니다. 실행 중에 예기치 못한 상황이 발생해서 프로그램이 죽는 상황이 발생하기도 하는데요. 프로그램이

devpouch.tistory.com

출처 : https://blockdmask.tistory.com/537

 

[python] 파이썬 예외처리 try, except, else, finally 사용 방법

안녕하세요. BlockDMask입니다. 오늘은 파이썬에서 예외를 처리하는 방법에 대해서 이야기해보려 합니다. <목차> 1. 예외란? 예외처리 방법 try except 2. 예외 처리 방법 try, except, else, finally  2-1) try..

blockdmask.tistory.com

Comments