Python

Python_04_예외처리

5_ssssseung 2021. 4. 6. 09:17

예외처리

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