About Python – “예외처리 – try, except, finally, raise”

About Python – “예외처리 – try, except, finally, raise”

2월 1, 2022

예외 처리란?

예외 처리(例外 處理) 또는 오류 처리는 일반적인 실행의 흐름을 바꾸는 몇 가지 조건을 처리하도록 설계한 프로그래밍 언어의 개념이나 컴퓨터 하드웨어 구조를 말한다.

일반적으로 프로그램이 처리되는 동안 특정한 문제가 일어났을 때 처리를 중단하고 다른 처리를 하는 것을 예외 처리라고 한다.

위키백과

여러 상황에서 발생하는 오류를 무시하고 다른 작업을 처리하는 것을 예외 처리라고 합니다.

파이썬의 try, except

print(x)
# NameError: name 'x' is not defined

위의 코드는 정의되지 않은 x를 사용하려고 했기 때문에 오류가 발생합니다.

위의 오류를 try, except 문을 사용하여 예외 처리를 해 보겠습니다. 먼저 파이썬의 try, except문은 다음과 같이 사용합니다.

try:
    # 오류가 발생할 가능성이 있는 내용
    # 오류가 발생하면 except 블록을 수행
except:
    # 오류가 발생하면 수행될 내용

아래의 코드와 같이 예외처리를 할 수 있습니다.

try:
    print(x)
except:
    print("프로그램에 오류가 발생하였습니다.")
    
    # 프로그램에 오류가 발생하였습니다.

기본적인 try, except 문은 오류가 발생하기만 하면 except 블록을 수행하도록 합니다. NameError가 발생했지만 예외처리가 되는 것을 확인할 수 있습니다.

try:
    print(x)
except IndexError:
# except [발생한 오류]: 로 해당 오류가 발생했을 때에만 예외처리를 하도록 할 수 있습니다.
    print("프로그램에 오류가 발생하였습니다.")

    # 프로그램에 오류가 발생하였습니다.

위의 코드의 경우 try 블록에서 NameError가 발생하지만, IndexError에 관한 except문을 작성했으므로 예외처리가 되지 않는 것을 확인할 수 있습니다. 아래처럼 여러 개의 오류를 처리하도록 할 수 있습니다.

try:
    print(x)
    a = 1229/0
except IndexError:
    print("IndexError 발생!")
except NameError:
    print("NameError 발생!")
except ZeroDivisionError:
    print("ZeroDivisionError 발생!")

    # NameError 발생!

위의 try 블록의 코드를 살펴봅시다. print(x)에서는 NameError가, 1229/0에서는 ZeroDivisionError 가 발생할 것이 자명해 보입니다. 하지만 맨 처음 발생한 NameError가 발생한 후 except문이 수행되어 그 이후의 오류는 발생하지 않았습니다.

아래의 경우처럼 여러 종류의 오류를 동시에 처리하기 위해서는 괄호 안에 오류의 종류를 묶어주면 됩니다.

try:
    print(x)
    a = 1229/0
except (IndexError, NameError, ZeroDivisionError) as e:
    print(e)

except [발생한 오류] as [변수] 와 같이 코드를 작성하면 변수 에 오류 메시지가 담깁니다.

try:
    print(x)
except NameError as a:
    print(a)
    print(type(a))

    # <class 'NameError'>
    # name 'x' is not defined

아래와 같이 pass라는 키워드를 사용해서 오류가 발생해도 아무것도 하지 않고 오류를 회피하도록 할 수 있습니다.

try:
    print(x)
except NameError as a:
    pass

파이썬의 try, finally

try, finally문을 사용하면 에러 발생 여부와는 상관없이 finally문 아래의 블록이 수행됩니다.

try:
    print(x)
finally:
    print("finally는 에러 발생 여부와 상관없이 수행됩니다.")

# NameError: name 'x' is not defined
# finally는 에러 발생 여부와 상관없이 수행됩니다.

try에서 에러가 발생했고 그것과는 관계없이 finally 블록이 수행되는 것을 확인할 수 있습니다.

try:
    # x = 1
    print(x)
except NameError as e:
    print(e)
finally:
    print("finally는 에러 발생 여부와 상관없이 수행됩니다.")

# NameError: name 'x' is not defined
# finally는 에러 발생 여부와 상관없이 수행됩니다.

2줄의 주석을 풀고 위의 코드를 실행해 보아도 finally 블록은 수행되는 것을 확인할 수 있습니다.

파이썬의 raise 명령어

try:
    raise NameError
finally:
    pass

# NameError

위처럼, raise라는 명령어를 통해서 에러를 일부러 발생시킬 수 있습니다.

파이썬의 Exception 클래스

여러 오류들의 종류인 NameError, IndexError 와 같은 것들은 파이썬에서 내장 클래스로 정의되어 있습니다. 전에 파이썬의 클래스를 설명할 때에 클래스를 종이접기 책에 비유한 적이 있는데, 마찬가지로 우리는 Exception클래스를 상속하여 원하는 예외의 종류를 만들 수 있습니다.

class NoError(Exception):
    def __str__(self):
        return "no를 입력하지 마세요!"

def yesOrYes(yes):
    if yes == "no":
        raise NoError
    print(yes)

try:
    yesOrYes("no")
except NoError as e:
    print(e)

# no를 입력하지 마세요!

위의 1줄에서 3줄까지의 코드를 보면 Exception클래스를 상속받은 나만의 예외 NoError를 정의했습니다. 밑의 __str__ 메서드는 오류 메시지를 출력할 때에 호출되는 메소드입니다.

밑의 yesOrYes() 함수를 정의한 내용(5줄에서 8줄까지의 코드)을 살펴보겠습니다. 매개변수로 “no“가 들어오면 위에서 만들었던 나만의 예외인 NoError를 발생하도록 되어 있네요.

그러면 10줄에서 13줄까지의 코드처럼 예외처리를 할 수 있습니다. yesOrYes("no") 로 함수를 호출하였기 때문에 만들었던 NoError가 발생하고, 그것의 메시지인 "no를 입력하지 마세요!" 가 출력되는 것을 확인할 수 있습니다.

Leave A Comment

Avada Programmer

Hello! We are a group of skilled developers and programmers.

Hello! We are a group of skilled developers and programmers.

We have experience in working with different platforms, systems, and devices to create products that are compatible and accessible.