본문 바로가기

python

python - 에러 및 예외 처리

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

대부분 에러 문제는 실행 프로세스에서 발생함

linter : 코드 스타일로 문법체크를 해주기 때문에 문법적 에러는 거의 없다고 봐도 무방함.

깔끔하게 정리하는 게 더 중요하다.

실행 프로세스 런타임 에러 종류

SyntaxError : 잘못된 문법

print('test) 
if True
	pass
   
X => Y

위와 같은 잘못된 문법 에러이다.

 

NameError : 참조 변수 없음

 a = 1
 b = 2
 
 print(c) ??

ZeroDivisionError : 0 나누기 에러

print(10 / 0)

IndexError : 인덱스 범위 오버

x = [10, 20, 30]
print(x[0])
print(x[3]) ??? # 인덱스 오버됌 2까지밖에 없는데?

KeyError 

dic = { 'name' : 'kim', 'age' : 33, 'City' : 'Seoul' }
print(dic['hobby'])
print(dic.get('hobby'))

get 메서드를 사용하면 keyerror 없이 none이 호출된다.

※ get 사용을 하도록 하자!

 

AttributeError : 모듈, 클래스에 있는 잘못된 속성 사용시에 예외

import time

print(time.time())
print(time.month()) ???

time 모듈에서 time() 함수, gmtime(), localtime() 함수 등이 있고 month() 함수는 없기 때문에 에러가 발생한다.

 

ValueError : 참조 값이 없을 때 발생

x = [1, 5, 9]
x.remove(10)
x.index(10)

x 가 list 형태로 되있기 때문에 remove() 메서드 사용이 가능하다.

이왕 공부하는 김에 list 내장 함수 및 메서드에 대해 정리해보고 넘어간다.

FileNotFoundError : 파일이 해당 위치에 없을때 발생

 

TypeError : 타입이 다르면 연산 불가능..

x = [1,2]
y = (1,2)
z = 'test'

print(x + y) ??
print(x + z) ??
print(x + list(y))

항상 예외가 발생하지 않을 것으로 가정하고 먼저 코딩 후

런타임 예외 발생시 예외 처리 코딩을 할 것을 권장한다. (EAFP 코딩 스타일)

EAFP ? - It’s Easier to Ask Forgiveness than Permission 허락을 구하는 것 보다 용서를 구하는 것이 쉽다.

▶ 일단 수행 시키고(try), 에러가 발생하면 그때 처리한다(except)

예외 처리 기본

try : 에러가 발생할 가능성이 있는 코드 실행

except : 에러명 1

except : 에러명 2

else : 에러 발생하지 않았을 경우 실행

finally : 항상 실행

 

name = ['Kim','Lee','Park']

try : # 파일 가져올 때, 핵심 코드 리소스가 들어간다.
	z = 'Kim' # 'Kim' : Not Error , 'Cho' : Error
    x = name.index(z) # 'Kim' 위치 인덱스 값은 0 => x 에 저장
    print('{} Found it! in name'.format(z, x+1))
except ValueError :
	print('Not Found it! - Occurred ValueError!')
else :
	print('OK! else!')

위 코드를 보면 z 값에 Kim 을 넣고 name list 안에 Kim 인덱스 값을 찾고 x 에 저장한다.

format 메서드를 이용해 {} 안에 문자열을 넣어준다.

name 안에 값이 없으면 'Cho'의 경우 에러가 발생하는데 except 문을 통해 예외가 발생했을 때 처리될 코드가 실행된다.

try 의 경우 함수가 아니므로 stackframe을 만들지 않으므로 내부에서 선언한 변수도 내외(안팎)에서 상호 사용하다.

 

except 예외이름 :

                  실행코드

 

의 경우 특정 예외만 처리한다.

 

위 코드에서는 예외이름이 'ValueError' 이므로 그 외 에러에 대해서는 모두 else로 넘어간다.

하지만 그냥 except : 로 하면 모든 예외를 포함하고 예외가 발생하지 않으면 else 절이 있는 코드가 실행, 출력된다.

 

try : # 파일 가져올 때, 핵심 코드 리소스가 들어간다.
    z = 'Kim' # 'Kim' : Not error
    x = name.index(z)
    print('{} Found it! in name'.format(z,x+1))
except : 
    print('Not Found it ! - Occurred Error!')
else :
    print('OK! else!')
finally : # 외부 프로그램 연결 스트림 작업시 나중에 연결을 끊어주는 무조건적인 실행이 요구될 때 사용
    print('finally ok!')

except 가 발생하면 except 문이 실행되고, finally 는 반드시 실행된다. 나중에 연결을 끊어주는 무조건적인 실행을 요구할 때 사용한다. else 문은 except 가 실행되지 않으면 실행된다.

 

 

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

try:
    print('Try')
finally:
    print("finally ok!")

 

try : # 파일 가져올 때, 핵심 코드 리소스가 들어간다.
    z = 'Kim' # 'Kim' : Not error
    x = name.index(z)
    print('{} Found it! in name'.format(z, x+1))
except ValueError as l: # 예측 확률이 높은 예외를 맨위부터 처리한다. # as alias 사용가능
    print('Not Found it ! - Occurred ValueError!')
except IndexError : 
    print('Not Found it ! - Occurred IndexError!')
except Exception : # all 예외 처리는 마지막에 둔다.
    print('Not Found it ! - Occurred Error!')
else :
    print('OK! else!')

except Exception : => all 예외 처리는 마지막에 둔다.

 

# 예외 발생 : raise
# raise 키워드로 예외 직접 발생

try :
    a = 'John'
    if a == 'Kim':
        print("OK! 허가")
    else :
        raise ValueError # 외부 데이터가 들어올 떄 예외 발생을 일부러 시켜 관리자가 알아야 할때
except ValueError:
    print('문제발생')
except Exception as f :
    print(f)
else:
    print('OK!')