Exception / File / Log Handling

💡 생각해보기
프로그램 사용할 때 일어나는 오류들

  • 주소를 입력하지 않고 배송 요청
  • 저장도 안 했는데 컴퓨터 전원이 나감
  • 게임 아이템 샀는데 게임에서 튕김
  • 예상치 못한 많은 일( 예외 ) 들이 생김

Exception

예상 가능한 예외

  • 발생 여부를 사전에 인지할 수 있는 예외
  • 사용자의 잘못된 입력, 파일 호출 시 파일 없음
  • 개발자가 반드시 명시적으로 정의 해야한다

예상 불가능한 예외

  • 인터프리터 과정에서 발생하는 예외, 개발자 실수
  • 리스트의 범위를 넘어가는 값 호출, 정수 0으로 나누는 경우
  • 수행 불가시 인터프리터가 자동 호출
  • 예외가 발생할 경우 후속 조치 등 대처가 필요하다

    1) 없는 파일 호출 -> 파일 없음을 알림
    2) 게임 이상 종료 -> 게임 정보 저장
    ✨ 프로그램 = 제품, 모든 잘못된 상황에 대처가 필요하다( Exception Handling )

파이썬의 예외 처리

📍 try ~ except 문법

try:
	# 예외 발생 가능 코드
except <Exception Type>:
	# 예외 발생시 대응하는 코드

📍 0으로 숫자를 나눌 때 예외처리 하기

for i in range(10):
	try:
    	print(10 / i)
    except ZeroDivisionError:
    	print('Not divided by 0')

📍 Built-in Exception( 기본적으로 제공하는 예외 )

파이썬의 예외 처리 예시

📍 예외 정보 표시하기

for i in range(10):
	
    try:
    	print(10 / i )
    except ZeroDivistionError as e:
    	print(e)
        print('Not divided by 0')

📍 try ~ except ~ else

try:
	# 예외 발생 가능 코드
except <Exception Type>:
	# 예외 발생시 동작하는 코드
else:
	# 예외가 발생하지 않을 때 동작하는 코드
for i in range(10):
	try:
		result = 10 / i
    except ZeroDivisionError:
    	print('Not divided by 0')
    else:
    	print(10 / i)

📍 try ~ except ~ finally

try:
	# 예외 발생 가능 코드
except <Exception Type>:
	# 예외 발생시 동작하는 코드
finally:
	# 예외 발생 여부와 상관없이 실행
try:
	for i in range(1, 10):
    	result = 10 // i
        print(result)
except ZeroDivisionError:
	print('Not divided by 0')
finally:
	print('종료되었습니다')

📍 raise

  • 필요에 따라 강제로 Exception을 발생
raise < Exception Type> ( 예외정보 )
while True:
	value = input('변환할 정수 값을 입력해주세요')
    for digit in value:
    	if digit not in '0123456789':
        	raise ValueError('숫자값을 입력하지 않으셨습니다')
    print('정수값으로 변환된 숫자 -', int(value))

📍 assert

  • 특정 조건에 만족하지 않을 경우 예외 발생
assert 예외조건
def get_binary_number(decimal_number):
	assert isinstance(decimal_number, int)
    return bin(decimal_number)
    
print(get_binary_number(10))

File Handling

  • File system, 파일 시스템
  • OS에서 파일을 저장하는 트리구조 저장 체계

파일의 기본 체계 👉 파일 vs 디렉토리

디렉토리( Directory)

  • 폴더 또는 디렉토리로 불림
  • 파일과 다른 디렉토리를 포함할 수 있다

파일( File )

  • 컴퓨터에서 정보를 저장하는 논리적인 단위
  • 파일은 파일명과 확장자로 식별
  • 실행, 쓰기, 읽기 등을 할 수 있음

파일의 종류

  • 기본적인 파일 종류로 text파일과 binary파일로 나눔
  • 컴퓨터는 text파일을 처리하기 위해 binary 파일로 변환시킴
  • 모든 text 파일도 실제는 binary파일,
  • ASCII/Unicode 문자열 집합으로 저장되어 사람이 읽을 수 있다

📍 python file I/O

  • 파이썬은 파일 처리를 위해 open 키워드를 사용
f = open('<파일 이름>', '접근 모드')
f.close()

  • read() txt 파일 안에 있는 내용을 문자열로 반환
f = open('i_have_a_dream.txt', 'r')
contents = f.read()
print(contents)
f.close()
  • with 구문과 함께 사용하기
with open(i_have_a_dream.txt', 'r') as my_file:
	contents = my_file.read()
    print(type(contents), contents)

📍 파이썬의 File Read

  • 한 줄씩 읽어 List Type으로 반환
with open('i_have_a_dream.txt', 'r') as my_file:
	content_list = my_file.readlines()	# 파일 전체를 list로 반환
    print(type(content_list))	# Type 확인
    print(content_list)	# 리스트 값 출력
  • 실행 시 마다 한 줄 씩 읽어 오기
with open('i_have_a_dream.txt', 'r') as my_file:
	i = 0
    while True:
    	line = my_file.readline()
        if not line:
        	break
        print(str(i) + '===' + line.replace('\n', ''))	# 한줄씩 값 출력
        i += 1
  • 단어 통계 정보 산출
with open("i_have_a_dream.txt", "r") as my_file:
    contents = my_file.read()
    word_list = contents.split(" ") 
    #빈칸 기준으로 단어를 분리 리스트
    line_list = contents.split("\n") 
    #한줄 씩 분리하여 리스트

print("Total Number of Characters :", len(contents))
print("Total Number of Words:", len(word_list))
print("Total Number of Lines :", len(line_list))
  • mode는 w, encoding=utf8
f = open("count_log.txt", 'w', encoding="utf8")
for i in range(1, 11):
    data = "%d번째 줄입니다.\n" % i
    f.write(data)
f.close()
  • modea는 추가모드
with open("count_log.txt", 'a', encoding="utf8") as f:
for i in range(1, 11):
	data = "%d번째 줄입니다.\n" % i
f.write(data)

파이썬의 directory 다루기

📍 os 모듈을 사용하여 Directory 다루기

import os
os. mkdir('log')

📍 디렉토리가 있는지 확인하기

if not os.path.isdir('log'):
	os.mkdir('log')

Log 파일 생성하기

  • 디렉토리가 있는지
  • 파일이 있는지 확인 후
import os

if not os.path.isdir('log'):
	os.mkdir('log')
if not os.path.exists('log/count_log.txt'):
	f = open('log/count_log.txt', 'w', encoding='utf8')
    f.write('기록이 시작됩니다\n')
    f.close()
    
with open('log/count_log.txt', 'a', encoding='utf8') as f:
	import random, datetime
    for i in range(1, 11):
    stamp = str(datetime.datetime.now())
    value = random.random() * 1000000
    log_line = stamp + '\t' + str(value) +'값이 생성되었습니다' + '\n'
    f.write(log_line)

pickle

  • 파이썬의 객체를 영속화( persistence )하는 built-in 객체
  • 데이터, object등 실행중 정보를 저장 -> 불러와서 사용
  • 저장해야하는 정보, 계산 결과( 모델 ) 등 활용일 많다
import pickle

f = open('list.pickle', 'wb')
test = [1, 2, 3, 4, 5]
pickle.dump(test, f)
f.close()
f = open(list.pickle', 'rb')
test_pickle = pickle.load(f)
print(test_pickle)
f.close()

Logging Handling

로그 남기기 - Logging

  • 프로그램이 실행되는 동안 일어나는 정보 기록을 남기기
  • 유저의 접근, 프로그램의 Exception, 특정 함수의 사용
  • console 화면에 출력, 파일에 남기기, DB에 남기기 등
  • 기록된 로그를 분석하여 의미있는 결과를 도출 할 수 있다
  • 실생시점에서 남겨야하는 기록, 개발시점에서 남겨야하는 기록이 있다

print vs logging

  • 기록을 print로 남기는 것도 가능함
  • 그러나 Console 창에만 남기는 기록은 분석시 사용불가
  • 때로는 레벨별( 개발, 운영 )로 기록을 남길 필요도 있다
  • 모듈별로 별도의 logging을 남길필요도 있다
  • 이러한 기능을 체계적으로 지원하는 모듈이 필요!!

logging 모듈

import logging

logging.debug("틀렸잖아!")
logging.info("확인해")
logging.warning("조심해!")
logging.error("에러났어!!!")
logging.critical ("망했다...")

logging level

  • 프로그램 진행 상황에 따라 다른 Level의 Log를 출력
  • 개발 시점, 운영 시점 마다 다른 Log가 남을 수 있도록 지원
  • DEBUG > INFO > WARNING > ERROR > Critical
  • Log 관리시 가장 기본이 되는 설정 정보

configparser

  • 프로그램의 실행 설정을 file에 저장
  • Section, Key, Value 값의 형태로 설정된 설정 파일을 사용
  • 설정파일을 Dict type으로 호출 후 사용
import configparser

config = configparser.ConfigParser()
config.sections()

config.read('example.cfg')
config.sections()

for key in condig['SectionOne']:
	print(key)
    
config['SectionOne']['status']

argparser

  • Console 창에서 프로그램 실행시 Setting 정보를 저장
  • 거의 모든 Console 기반 Python 프로그램 기본으로 제공
  • 특수 모듈도 많이 존재하지만( TF ), 일반적으로 argparse를 사용
  • Command-Line Option 이라고 부른다

좋은 웹페이지 즐겨찾기