09 에러 및 예외 처리

09 에러 및 예외 처리

완벽한 프로그램은 없고, 에러는 늘 발생한다. 우리는 발생한 에러에 대해 적절한 조치를 취해줘야한다. 항상 예외가 발생하지 않을 것으로 가정하고 먼저 코딩하고, 그 후 런타임 예외 발생시 예외 처리 코딩 권장 (EAFP 코딩 스타일)

예외 종류

문법적으로 에러가 없지만, 코드 실행(런타임) 프로세스에서 발생하는 예외 처리도 중요

  • linter: 코드 스타일, 문법 체크
  • SyntaxError: 잘못된 문법
    print('Test)
    if True
     pass
    x => y
    
  • NameError: 참조변수 없음
    a = 10
    b = 15
    print(c)
    # c는 선언한 적 없음
    
  • ZeroDivisionError: 0 나누기 에러
    print(10 / 0)
    
  • IndexError: 인데스 범위 오버
    x = [10, 20, 30]
    print(x[0])
    print(x[3]) # 예외 발생
    
  • KeyError
    dic = {
     'Name' : 'Kim',
     'Age': 33,
    }
    print(dic['asdf'])
    print(dic.get('hobby')) # get 메소드 추천, 없으면 None 반환
    
  • AttributeError: 모듈, 클래스에 있는 잘못된 속성 사용시에 예외
    import time
    print(time.time())
    print(time.month())
    
  • ValueError: 참조 값이 없을 때 발생
    x = [1, 5, 9]
    x.remove(10)
    x.index(10)
    
  • FileNotFoundError: 파일이 못 찾을 때 발생
    f = open('test.txt', 'r')
    
  • TypeError ```python x = [1, 2] y = (1, 2) z = ‘test’ print(x + y) #예외 print(x + z)

print(x + list(y)) # 형 변환해서 해결


#### 예외 처리 기본 문법
```python
try : 에러가 발생할 가능성이 있는 코드 실행
except : 에러명1
except : 에러명2
else : 에러가 발생하지 않았을 경우 실행
finally : 항상 실행

예제1

에러명을 명시해 주기

name = ['kim', 'lee', 'park']

try:
    z = 'kim' # 리스트에 없는값 하면 에러 발
    x = name.index(z)
    print('{} Found it! in name {}'.format(z, x+1))
except ValueError:
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')

예제2

에러명 명시 안하기

try:
    z = 'ki2m'
    x = name.index(z)
    print('{} Found it! in name {}'.format(z, x+1))
except: # 에러명 없이하면 여기에 다 들어
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')

예제3

finally 사용

try:
    z = 'kim2'
    x = name.index(z)
    print('{} Found it! in name'.format(z, x+1))
except:
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')
finally:
    # db 연결 끊는것 처럼, 에러가 안발생해도 끊고, 발생해도 끊을 때 사용하면 좋음
    print('finally ok!')

예제4

예외 처리는 하지 않지만, 무조건 수행되는 코딩 패턴

try:
    print('Try')
finally:
    print('Ok Finally')

예제5 - 계층적으로 처

try:
    z = 'kim2'
    x = name.index(z)
    print('{} Found it! in name {}'.format(z, x+1))
except ValueError as l: # 에러 메세지 표시
    print('Not found it! - ValueError!')
except IndexError:
    print('Not found it! - IndexError!')
except Exception: # 가장 마지막에 두기
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')
finally:
    # db 연결 끊는것 처럼, 에러가 안발생해도 끊고, 발생해도 끊을 때 사용하면 좋음
    print('finally ok!')

예제6

예외 발생 : raise raise 키워드로 예외 직접 발생시킬 수 있다.

try:
    a = 'Ki2m'
    if a == 'Kim':
        print('ok 허가!')
    else:
        raise IndexError # 내가 규정하기
except IndexError:
    print('문제 발생!')
except Exception as f:
    print(f) # 에러 메세지가 없어서 출력이 안될것이다.
    print('다른 오류 발생')
else:
    print('Ok!')