TIL

TIL.37 예외처리하기(try, except)

codermun 2020. 11. 14. 21:30
728x90
반응형

## 예외 처리 사용하기

## 예외(exception) == 코드를 실행하는 중에 발생한 에러를 뜻함

def ten (x):
    return 10 / x

print(ten(2))
# 5.0

## 분모를 0으로 넣게 될 경우 실행 젱어가 발생하는데 이런 상황을 예외라고 한다.

print(ten(0)) 

Traceback (most recent call last):

  File "c:/Users/user/Desktop/python3_실습/38.1예외처리사용하기.py", line 9, in <module>

    print(ten(0))

  File "c:/Users/user/Desktop/python3_실습/38.1예외처리사용하기.py", line 6, in ten

  return 10 / x
 
 ZeroDivisionError: division by zero

## ZeroDivisionError뿐만 아니라 지금까지 만난 AttributeError, NameError, TypeError 등

    다양한 에러들도 모두가 예외이다.


## try , except 사용하기

## 이러한 예외가 발생했을 때도 스크립트 실행을 중단하지 않고 계속 실행하게 해주는 예외 처리 방법으로 

     try except가 있다.

# try:

#     실행할 코드

# except:

#     예외가 발생했을 때 처리하는 코드

 

# 숫자를 0으로 나누었을때 예외 처리

try:
    x = int(input('나눌 숫자를 입력하세요: '))
    y = 10 / x
    print(y)
except:    # 예외가 발생했을 때 실행됨
    print('예외가 발생했습니다.')

# 나눌 숫자를 입력하세요: 0 (입력)

# 예외가 발생했습니다.

## 위에서는 숫자를 0으로 나눌때 except 예외 처리를 해주었다.

## 특히 예외가 발생하면 해당 줄에서 코드 실행을 중단하고 바로 except로 가서 코드를 실행한다.

## 즉, try의 y = 10 / x 를 비롯하여 그 아래줄에 있는 print(y)도 실행되지 않는다.

## try 의 코드가 예외 없이 잘 실행되면 except의 코드는 실행되지 않고 그냥 넘어간다.


## 특정 예외만 처리하기

## except에 예외 이름을 지정해서 특정 예외가 발생했을 때만 처리 코드를 만들 수 있다.

# try:

#     실행할 코드

# except 예외이름:

#     예외가 발생했을 때 처리하는 코드

y = [10, 20, 30]

try:
    index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split())
    print(y[index] / x)
except ZeroDivisionError:    # 숫자를 0으로 나눠서 에러가 발생했을 때 실행됨
    print('숫자를 0으로 나눌 수 없습니다.')
except IndexError:           # 범위를 벗어난 인덱스에 접근하여 에러가 발생했을 때 실행됨
    print('잘못된 인덱스입니다.')


# 인덱스와 나눌 숫자를 입력하세요: 2 0
# 숫자를 0으로 나눌 수 없습니다.


# 인덱스와 나눌 숫자를 입력하세요: 3 2
# 잘못된 인덱스입니다.

## except에 예외이름을 지정하여 0으로 나누면 ZeroDivisionError:의 처리 코드가 실행되고

## 인덱스에 3을 지정하면 범위를 벗어나게 됩니다. 이때는 except IndexError:의 처리 코드가 실행된다.


## 예외의 에러 메시지 받아오기

## except 뒤에 as 변수를 지정하면 발생한 예외의 에러 메시지를 확인하여 

   어떠한 에러가 발생하였는지 확인 할 수 있다.

# try:

#     실행할 코드

# except 예외 as 변수:

#     예외가 발생했을 때 처리하는 코드

## 보통 변수에는 ( exception)의 e를 따서 변수 이름을 e로 작성한다.

y = [10, 20, 30]

try:

    index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split())
    print(y[index] / x)
except ZeroDivisionError as e:                    # as 뒤에 변수를 지정하면 에러를 받아옴
    print('숫자를 0으로 나눌 수 없습니다.', e)    # e에 저장된 에러 메시지 출력
except IndexError as e:
    print('잘못된 인덱스입니다.', e)


# 인덱스와 나눌 숫자를 입력하세요: 2 0
# 숫자를 0으로 나눌 수 없습니다. division by zero

# 인덱스와 나눌 숫자를 입력하세요: 3 2
# 잘못된 인덱스입니다. list index out of range

## 단, 예외가 여러 개 발생하더라도 먼저 발생한 예외의 처리 코드만 실행됩니다

    (또는, 예외 중에서 높은 계층의 예외부터 처리된다. 기반 클래스 > 파생 클래스 순)

## 모든 예외의 에러 메시지를 출력하고 싶다면 다음과 같이

     except에 Exception을 지정하고 as 뒤에 변수를 넣으면 된다.

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

    print('예외가 발생했습니다.', e)

### 이처럼 예외 처리는 에러가 발생하더라도 스크립트의 실행을 중단시키지 않고 계속 실행하고자 할 때 사용한다.


## 예외 계층

# 예외도 클래스 상속으로 구현되며 다음과 같은 계층으로 이루어져 있습니다. 보통 파이썬에서 새로운 예외를 만들 때는 Exception을 상속받아서 구현한다.

# 전체 계층도는 파이썬 공식 문서를 참조하자.

# Built-in Exceptions: https://docs.python.org/3/library/exceptions.html#exception-hierarchy

 

Built-in Exceptions — Python 3.9.0 documentation

Built-in Exceptions In Python, all exceptions must be instances of a class that derives from BaseException. In a try statement with an except clause that mentions a particular class, that clause also handles any exception classes derived from that class (b

docs.python.org

 


## else와 finally 사용하기

## tyr except 문에서 else 사용하기

## 예외가 발생하지 않았을 때 코드를 실행하는 else를 사용해보자

## 다음과 같이 else는 except 바로 다음에 와야 하며 except를 생략할 수 없다. (순서 및 생략 불가)

# try:

#     실행할 코드

# except:

#     예외가 발생했을 때 처리하는 코드

# else:

#     예외가 발생하지 않았을 때 실행할 코드

try:
    x = int(input('나눌 숫자를 입력하세요: '))
    y = 10 / x
except ZeroDivisionError:    # 숫자를 0으로 나눠서 에러가 발생했을 때 실행됨
    print('숫자를 0으로 나눌 수 없습니다.')

else:                        # try의 코드에서 예외가 발생하지 않았을 때 실행됨
    print(y)

## 예외가 발생하지 않았알때는 else의 print(y) 실행

## 예외가 발생하였을때는 except의 print('숫자를 0으로 나눌 수 없습니다.') 실행


## try except 문에서의 finally 사용하기

## finally == 예외 발생 여부와 상관없이 항상 코드를 실행하는 한다.

## finally는 except와 else를 생략할 수 있다. (생략 가능)

# try:

#     실행할 코드

# except:

#     예외가 발생했을 때 처리하는 코드

# else:

#     예외가 발생하지 않았을 때 실행할 코드

# finally:

#     예외 발생 여부와 상관없이 항상 실행할 코드

try:
    x = int(input('나눌 숫자를 입력하세요: '))
    y = 10 / x
except ZeroDivisionError:    # 숫자를 0으로 나눠서 에러가 발생했을 때 실행됨
    print('숫자를 0으로 나눌 수 없습니다.')
else:                        # try의 코드에서 예외가 발생하지 않았을 때 실행됨
    print(y)
finally:                     # 예외 발생 여부와 상관없이 항상 실행됨
    print('코드 실행이 끝났습니다.')


# 나눌 숫자를 입력하세요: 2
# 5.0
# 코드 실행이 끝났습니다.


# 나눌 숫자를 입력하세요: 0
# 숫자를 0으로 나눌 수 없습니다.
# 코드 실행이 끝났습니다.

## 숫자를 0으로 나누어 예외가 발생하지만 finally의 print('코드 실행이 끝났습니다.')는 항상 실행되는 걸 볼 수 있다.


#### try 안에서 만든 변수는 try 바깥에서 사용할 수 있나요? ####

## try는 함수가 아니므로 스택 프레임을 만들지 않는다.

# 따라서 try 안에서 변수를 만들더라도 try 바깥에서 사용할 수 있다. 물론 except, else, finally에서도 사용할 수 있다.

728x90
반응형