예외처리
1. 에러(Error)
발생할 수 있는 에러의 종류를 확인해봅시다.
1.1 문법 에러(Syntax Error)
문법 에러가 있는 프로그램은 실행되지 않습니다.
- 에러 발생 시
SyntaxError
라는 키워드와 함께, 에러의 상세 내용을 보여줍니다. 파일이름
과줄번호
,^
문자를 통해 파이썬이 코드를 읽어 들일 때(parser
) 문제가 발생한 위치를 표현합니다.parser
는 줄에서 에러가 감지된 가장 앞의 위치를 가리키는 작은 ’화살표(^
)’를 표시합니다.
if True:
print('참')
else
print('거짓')
File "<ipython-input-1-04c4e0453d50>", line 3
else
^
SyntaxError: invalid syntax
print('hi)
File "<ipython-input-3-8878a92e9096>", line 1
print('hi)
^
SyntaxError: EOL while scanning string literal
print('hi'
File "<ipython-input-4-b298cb61b70b>", line 1
print('hi'
^
SyntaxError: unexpected EOF while parsing
if True print('참')
File "<ipython-input-5-ae56d80f3d7b>", line 1
if True print('참')
^
SyntaxError: invalid syntax
2. 예외(Exception)
실행 도중 예상하지 못한 상황(exception)을 맞이하면, 프로그램 실행을 멈춥니다.
- 문법적으로는 옳지만, 실행시 발생하는 에러입니다.
- 아래 제시된 모든 에러는
Exception
을 상속받아 이뤄진다. - ZeroDivisionError
# 0으로 나눌수는 없습니다.
# ZeroDivisionError: division by zero10 * (1/0)
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-8-9798ae468072> in <module>
1 # 0으로 나눌수는 없습니다.
2 # division by zero
----> 3 10 * (1/0)
ZeroDivisionError: division by zero
- NameError
# 지역 혹은 전역 이름 공간내에서 유효하지 않는 이름
# 즉 정의되지 않은 변수를 호출 하였을 경우
# NameError: name 'abc' is not definedprint(abc)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-7-2beba0d725dd> in <module>
1 # 지역 혹은 전역 이름 공간내에서 유효하지 않는 이름
2 # 즉 정의되지 않은 변수를 호출 하였을 경우
----> 3 print(abc)
NameError: name 'abc' is not defined
- TypeError
# 자료형에 대한 타입 자체가 잘못 되었을 경우
# TypeError: unsupported operand type(s) for +: 'int' and 'str'1 + '1'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-9-166aa1c716a5> in <module>
1 # 자료형에 대한 타입 자체가 잘못 되었을 경우
----> 2 1 + '1'
TypeError: unsupported operand type(s) for +: 'int' and 'str'
# TypeError: type str doesn't define __round__ methodround('3.5')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-ebbc9f47e959> in <module>
----> 1 round('3.5')
TypeError: type str doesn't define __round__ method
- 함수호출 과정에서 다양한 오류를 확인할 수 있습니다. (1) 필수 argument 누락
# TypeError: sample() missing 1 required positional argument: 'k'import randomrandom.sample([1, 2, 3])
# random.sample([1, 2, 3], 1) 몇개 뽑을 건지 써죠야지!
[2]
- 함수호출 과정에서 다양한 오류를 확인할 수 있습니다. (2) argument 개수 초과
# TypeError: choice() takes 2 positional arguments but 3 were givenrandom.choice([1, 2, 3], 6)# random.choice([1, 2, 3]) 초이스는 하나만 뽑아주는거라 리스트만 쓰면됨
1
- ValueError를 확인해봅시다.
# 자료형에 대한 타입은 올바르나 값이 적절하지 않는 경우
# ValueError: invalid literal for int() with base 10: '3.5'int('3.5')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-13-8ea914687a01> in <module>
1 # 자료형에 대한 타입은 올바르나 값이 적절하지 않는 경우
----> 2 int('3.5')
ValueError: invalid literal for int() with base 10: '3.5'
# 존재하지 않는 값을 찾고자 할 경우
# ValueError: 3 is not in listnumbers = [1, 2]numbers.index(3)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-17-cbc1c8e40b60> in <module>
1 # 존재하지 않는 값을 찾고자 할 경우
2 numbers = [1, 2]
----> 3 numbers.index(3)
ValueError: 3 is not in list
- IndexError
# 존재하지 않는 index로 조회할 경우# IndexError: list index out of rangeempty_list = []empty_list[1]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-27-c0f998a72552> in <module>
1 # 존재하지 않는 index로 조회할 경우
2 empty_list = []
----> 3 empty_list[1]
IndexError: list index out of range
- KeyError
# 딕셔너리에서 Key가 없는 경우 songs = {'sia': 'candy cane lane'}songs['queen']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-28-fb506014f16e> in <module>
1 # 딕셔너리에서 Key가 없는 경우
2 songs = {'sia': 'candy cane lane'}
----> 3 songs['queen']
KeyError: 'queen'
- ModuleNotFoundError
# 모듈을 찾을 수 없는 경우import reque
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-30-6328ce215cab> in <module>
1 # 모듈을 찾을 수 없는 경우
----> 2 import reque
ModuleNotFoundError: No module named 'reque'
- ImportError
# 모듈을 찾았으나 가져오는 과정에서 실패하는 경우 (존재하지 않는 클래스/함수 호출)from random import sampl
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-32-9c395f6f4684> in <module>
1 # 모듈을 찾았으나 가져오는 과정에서 실패하는 경우 (존재하지 않는 클래스/함수 호출)
----> 2 from random import sampl
ImportError: cannot import name 'sampl' from 'random' (c:\users\jisu6\appdata\local\programs\python\python38\lib\random.py)
- KeyboardInterrupt
# 주피터 노트북에서는 정지 버튼이지만, 실제로 우리가 돌릴 때는 ctrl+c를 통해 종료하였을 때 발생한다.
# 사용자가 의도적으로 멈췄을 때while True: continue
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
<ipython-input-34-89cc33ee39df> in <module>
1 # 주피터 노트북에서는 정지 버튼이지만, 실제로 우리가 돌릴 때는 ctrl+c를 통해 종료하였을 때 발생한다.
2 while True:
----> 3 continue
KeyboardInterrupt:
3. 예외 처리(Exception Handling)
try
& except
try
문을 이용하여 예외 처리를 할 수 있습니다.
3.1 기초 문법
try:
<코드 블럭 1>
except (예외):
<코드 블럭 2>
try
아래의 코드블락(code block)이 실행된다.- 예외가 발생되지 않으면,
except
없이 실행이 종료 된다. - 예외가 발생하면, 남은 부분을 수행하지 않고,
except
가 실행된다.
# 사용자로부터 값을 받아 정수로 변환하여 출력해봅시다.
num = input('값을 입력하시오 : ')print(int(num))
# 사용자가 문자열을 넣어 해당 오류(ValueError)가 발생하면, 숫자를 입력하라고 출력해봅시다.
try:
num = input('값을 입력하시오 : ')
print(int(num))
except ValueError:
print('숫자를 입력하라니까!!')
3.2 에러 메시지 처리 as
as
키워드를 활용하여 에러 메시지를 보여줄 수도 있습니다.
활용법
try:
<코드 블럭 1>
except
예외
as err:
<코드 블럭 2>
# 에러 메세지를 넘겨줄 수도 있습니다.
try:
empty_list = []
print(empty_list[-1])
except
IndexError
as err:
print(f'{err}, 오류가 발생했습니다.')
3.3 복수의 예외 처리
하나 이상의 예외를 모두 처리할 수 있습니다.
괄호가 있는 튜플로 여러 개의 예외를 지정할 수 있습니다.
활용법
try: <코드 블럭 1>except (예외1, 예외2): <코드 블럭 2>try: <코드 블럭 1>except 예외1: <코드 블럭 2>except 예외2: <코드 블럭 3>
# 100을 사용자가 입력한 값으로 나눈 후 출력하는 코드를 작성해봅시다.
num = input('100으로 나눌 값을 입력하시오 : ')print(100/int(num))
# 문자열일때와 0일때 모두 처리를 해봅시다.
# 각각 다른 오류를 출력할 수 있습니다.
- 여기서 중요한 내용은 에러가 순차적으로 수행됨으로, 가장 작은 범주부터 시작해야 합니다.
else
- 에러가 발생하지 않는 경우 수행되는 문장은
else
를 이용한다. - 모든 except 절 뒤에와야 한다.
- try 절이 예외를 일으키지 않을 때 실행되어야만 하는 코드에 적절하다.
활용법
try: <코드 블럭 1>except 예외: <코드 블럭 2>else: <코드 블럭 3>
# else를 사용해봅시다.
finally
- 반드시 수행해야하는 문장은
finally
를 활용한다. - 즉, 모든 상황에 실행되어야만 하는 코드를 정의하는데 활용한다.
- 예외의 발생 여부과 관계없이 try 문을 떠날 때 항상 실행한다.
활용법
try: <코드 블럭 1>except 예외: <코드 블럭 2>finally: <코드 블럭 3>
# finally를 사용해봅시다.
try: print('성적 파일을 읽어옵니다.') data = {'python': 'A+'} data['java']except KeyError as err: print(f'{err}는 딕셔너리에 없는 키입니다.')finally: print('성적 파일을 종료합니다.')
3.4 예외 발생 시키기(Exception Raising)
raise
raise
를 통해 예외를 강제로 발생시킬 수 있습니다.
활용법
raise <에러>('메시지')
# raise를 사용해봅시다.
raise ZeroDivisionError('0으로 감히 나눠?')
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-35-4dc809046efd> in <module>
----> 1 raise ZeroDivisionError('0으로 감히 나눠?')
ZeroDivisionError: 0으로 감히 나눠?
[연습] raise
예외 발생시키기
리스트를 받아 평균을 반환하는 def avg(scores)를 작성하세요.
scores의 길이가 0인 경우
Exception
과 메시지를 발생시키세요.- 예) Exception: 학생이 없습니다.
정상적인 경우에는 결과를 return합니다.
# 아래에 코드를 작성하세요.
# 해당 코드를 통해 올바른 결과가 나오는지 확인하세요.avg([])
assert
assert
문은 예외를 발생시키는 다른 방법입니다.
보통 상태를 검증하는데 사용되며 무조건 AssertionError
가 발생합니다.
활용법
assert Boolean expression, error messageassert len([1, 2]) == 1, '길이가 1이 아닙니다.'
위의 검증식이 거짓일 경우를 발생합니다.
일반적으로 디버깅용도로 사용됩니다. 파이썬 문서
$ python code.pyTraceback (most recent call last): File "code.py", line 1, in <module> assert len([1, 2]) == 1, '길이가 1이 아닙니다.'AssertionError: 길이가 1이 아닙니다.$ python -O code.py
print('시작')raise ZeroDivisionError('0으로 감히 나눠?')print('끝')
시작
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-36-7b7601375801> in <module>
1 print('시작')
----> 2 raise ZeroDivisionError('0으로 감히 나눠?')
3 print('끝')
ZeroDivisionError: 0으로 감히 나눠?
print('시작')try : 1/0except: print('0으로 감히 나눠?')print('끝')
시작
0으로 감히 나눠?
끝
'Python' 카테고리의 다른 글
Python_06_모듈&패키지 (0) | 2021.04.09 |
---|---|
Python_05_데이터_구조 (0) | 2021.04.07 |
Python_03_함수 (0) | 2021.04.05 |
Python_02_제어문 (0) | 2021.04.04 |
Python_01_컨테이너 (0) | 2021.03.30 |