오류 및 예외 처리

Junho Song·2022년 12월 16일
0

Python

목록 보기
11/11

들어가면서

어느 언어나 그렇겠지만 파이썬으로 프로그래밍을 하다보면 여러 오류들을 경험하게 된다.

처음에 프로그래밍을 배울때는 간단한 사칙연산 식이나 str을 작성해놓고 실행했을때 오류메세지가 뜨면 당황스러웠는데 이제는 코딩을 실행하였을때 오류는 안뜨고 정답을 출력해주지 않을때 더욱 당황스럽다. 파이썬을 제대로 배우기 시작한지 1달정도 되었는데 이제 어느정도 성장 한 것이겠지...

오늘은 친절하게 고치라고 말해주는 오류들에 대해서 알아보겠다.

오늘도 출처가 되는 내용은 점프 투 파이썬이다. 거의 뭐 회사 직원이다 싶을 정도로 주변에 좋다고 알리는 중인데 전혀 관계없는 사람이다. 하지만 정말 좋은 책이라고 생각하니 혹여라도 파이썬 입문 초보자라면 꼭 이 책을 읽어보길 바란다.

서두가 길었으니 바로 본론으로 넘어간다.

오류의 종류

오류에는 정말 여러가지가 있는데 초보들이 가장 많이 맞닥뜨리는 오류들은 아래와 같다.

FileNotFoundError: No such file or directory: '파일이름'

ZeroDivisionError: division by zero

IndexError: list index out of range

위의 오류들은 없는 파일을 불러들이려고 하거나, 어떤 값을 0으로 나누거나, 리스트에 포함되어있는 데이터의 범위 밖의 값을 출력할때 발생한다.

오류를 예외로 처리하기

이러한 오류들이 나오지 않게 하기 위해서는 아래와 같이 try와 except문을 사용하면 된다. try 아래의 코드블록을 실행하고 오류가 없으면 그냥 넘어간다. 하지만 오류가 있으면 해당 코드블록의 내용은 except로 넘어가고 except에서 오류에 대한 내용을 어떻게 처리할지 결정한다.

ZeroDivisionError: division by zero를 실행시켜 예를 들어본다.

try:
	1/0
except:
	pass

만약 try, except를 사용하지 않고 1/0을 실행하면 ZeroDivisionError: division by zero 오류가 뜬다. 하지만 위와 같이 작성함으로써 try밑의 1/0은 except로 넘어가게 되고 except에서는 오류 값을 pass로 넘기면서 오류 메세지가 나오지 않게된다.

만약 특정하게 발생되는 오류와 동일한 오류일 경우에만 except블록을 수행하고 싶다면 아래와 같이 진행해주면 된다. 이 경우에는 해당 오류가 발생했을때 어떠한 기능을 수행하고 싶으면 아래와 같이 except 밑에 명령어를 입력해준다.

try:
	1/0
except ZeroDivisionError:
	print('0으로 나눌 수 없으니 분모에 다른 값을 입력해주세요')

위의 경우에서 더욱 나아가 발생하는 오류의 내용을 알고싶으면 아래와 같이 입력한다.

try:
	1/0
except ZeroDivisionError as e:
	print(e)

try... finally

아래와 같이 finally문은 try에서 중간에 오류가 발생해도 finally 아래의 코드 블록은 무조건 실행해준다.

try:
	1/0
    
finally:
	print(1/2)

fianlly 절 없이 try 절 밑에 printa(1/2)를 실행하면 fianlly 절 또는 except 절을 포함하라는 오류가 뜨지만 위의 코드를 실행하면 finally 밑의 print(1/2)가 실행되어 0.5를 출력해주고 그 밑에 ZeroDivisionError 오류가 보여지게 된다.

try... except... except..

try:
	4/0
	a=[1,2,3]
    print(a[3])

except ZeroDivisionError:
	print('0은 분모에 들어갈 수 없습니다')

except IndexError:
	print('인덱스 범위를 초과하였습니다.')

여러개의 오류를 동시에 처리해주려면 위와 같이 except절을 추가해가면서 처리해주면 된다. 다만 먼저 발생한 오류를 기준으로 해당 오류의 except절이 실행되고 그 뒤에 나오는 except절은 실행되지 않는다.

위의 except절은 아래와 같이 한줄에 사용될 수 있다.

try:
	4/0
	a=[1,2,3]
    print(a[3])

except (ZeroDivisionError, IndexError):
	print('분모가 0이거나 인덱스 범위를 초과한 코드가 있으니 수정해주세요.')

try... except... else

try문과 except문을 작성하고 나서 만약에 try문에서 오류가 없을때 특정한 코드를 실행하고 싶다면 else절을 통해 할 수 있다. 아래의 코드를 살펴보자.

try:
	age = int(input('나이를 입력하세요:'))

except:
	print('나이는 숫자만 가능합니다')

else:
	if 0<=age<=18:
    	print('미성년자는 출입 금지입니다.')
    elif age < 0:
    	print('당신은 아직 태어나지 않았습니다.')
    else:
    	print('환영합니다')

위의 코드를 실행했을때 만약 숫자가 아닌 다른 값이 입력되면 오류가 발생하면서 except문이 수행된다. 만약 숫자를 입력하여 오류가 발생하지 않으면 else절이 수행된다.

오류 회피

만약 특정 오류를 그냥 넘기고 싶다면 아래와 같이 작성하면 된다.

try:
	4/0

except ZeroDivisionError:
	pass

오류 발생시키기

프로그래밍을 하다보면 일부러 오류를 발생시켜야 하는 경우가 생길 수 있다고 한다. 현재의 나로써는 이해가 안되는 부분이니 점프 투 파이썬의 내용을 그대로 가지고 와서 실행해본다.

class Bird:
    def fly(self):
        raise NotImplementedError

파이썬에서는 raise 명령어를 통해 위와 같이 오류를 강제로 발생시키고 위의 코드는 Bird라는 클래스의 fly메서드는 자식 클래스가 생성될때 자식 클래스에 무조건 포함되거나 수정 되어야 한다는 의지를 보여준다.

NotImplementedError는 파이썬에 정의되어 있는 오류 중 하나로써 작성되어야 하는 코드가 구현되지 않았을때 일부러 오류를 일으키기 위해 사용된다.

만약 Eagle이라는 클래스에 위의 Bird 클래스를 상속 시키고 그 아래 fly메서드를 구현하지 않는다면 오류가 발생하는 것이다.

오류가 발생되지 않기 위해 아래와 같이 상속된 Eagle 클래스에 fly메서드를 구현해준다(overriding).

class Eagle(Bird):
	def fly(self):
    	print('very fast')

eagle = Eagle()
eagle.fly()

만약 위의 Eagle class 코드 블록에서 fly함수가 없다면 NotImplementedError가 뜬다.

예외 만들기

프로그램을 작성하는 도중 특수한 경우에 한해서 예외 처리를 할 수 있다. Exception는 파이썬의 내장 클래스 중 하나로 해당 클래스를 상속해서 예외를 만들어보자.

class MyError(Exception):
	def __str__(self):
    return '허용되지 않는 별명입니다.'

str 메서드를 통해 오류 메시지를 출혁했을때 오류가 보이도록 위와 같이 작성한다.

그리고 방금 배웠던 raise를 통해 위에 작성한 MyError 클래스의 에러가 발생되도록 한다.

아래와 같이 작성하면 MyError:허용되지 않는 별명입니다. 오류가 뜬다.

def say_nick(nick):
	if nick == '바보':
    	raise MyError()
    print(nick)

say_nick('천사')
say_nick('바보')

오류 메세지가 실행되지 않고 '허용되지 않는 별명입니다.'를 출력하고 싶다면 아래와 같이 코드를 작성하면 된다.


class MyError(Exception):
    def __str__(self):
        return '허용되지 않는 별명입니다.'

def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)

try:
    say_nick('천사')
    say_nick('바보')
except MyError as e:
    print(e)
profile
상위 1%의 금융데이터 분석가를 꿈꿉니다.

0개의 댓글