try/ finally블록
예외가 발생해도 정리코드를 실행해야할 때 사용
파일 핸들을 안전하게 닫기
def try_finally_example(filename):
print('* 파일 열기')
handle = open(filename, encoding = 'utf-8') #OSError가 발생할 수 있다
try:
print('* 데이터 읽기')
return handle.read()# UnicodedECODEeRROR이 발생할 수 있다.
finally:
print('* close() 호출')
handle.close() #try블록이 실행된 다음에 항상 이 블록이 실행딤
filename = 'random_data.txt'
with open(filename, 'wb') as f:
f.write(b'\xf1\xf2\xf3\xf4\xf5') #잘못된 utf-8 이진 문자열
data = try_finally_example(filename)
else 블록
전달할 예외를 명확히 구분
try 블록에 들어가는 코드가 줄어들게 되어서 가독성이 늘어남
import json
def load_json_key(data, key):
try:
print('* JSON 데이터 읽기')
result_dict = json.loads(data) # ValueError이 발생함
except Value Error as e:
print('* ValueError 처리')
raise KeyError(key) from e
else:
print('* 키 검색')
return result_dict[key]
모든 요소를 한꺼번에 사용하기
UNDEFINED = object()
def divide_json(path):
print('* 파일 열기')
handle = open(path, 'r+') #OSError가 발생할 수 있음
try:
print('* 데이터 읽기')
data = handle.read() #UnicodeDecoderError가 발생할 수 있음
print('* JSON 데이터 읽기')
op = json.loads(data) #ValueError가 발생할 수 있음
print('* 계산 수행')
value = (
op['numerator'] /
op['denominator']) #ZeroDivisionError가 발생할 수 있음
except ZeroDivisionError as e:
print('* ZeroDivisionError 처리')
return UNDEFINED
else:
print('* 계산 결과 쓰기')
op['result'] = value
result = json.dumps(op)
handle.seek(0)
handle.write(result)
return value
finally:
print('* close() 호출')
handle.close() #어떤 경우든 실행됨
try/finally 복합문을 사용하면 try블록이 실행되는 동안 예외가 발행하든 발생하지 않든 정리 코드 실행
else블록을 사용하면 try 블록 안에 넣을 코드를 최소화하고, try/except 블록과 성공적인 경우에 수행해야할 코드를 시각적으로 구분할 수 있다.
try 블록이 성공적으로 처리되고 finally 블록이 공통적인 정리 작업을 수행하기 전에 실행해야하는 동작이 있는 경우 else블록 사용