부스트캠프 AI Tech 4기

6. Exception/File/Log handling

StoneSeller 2022. 9. 23. 18:55

Exception Handling

▮ try ~ except 구문

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

 

 Built-in Exception

: 기본적으로 제공하는 예외

  • IndexError : List의 index 범위를 넘어갈 때
  • NameError : 존재하지 않는 변수를 호출 할 떄
  • ZeroDivisonError : 0으로 숫자를 나눌 때
  • ValueError : 변환할 수 없는 문자/숫자를 변환할 때

Exception으로 지정하면 특별히 지정하지 않아도 해당하는 Exception을 잡을 수 는 있다.

그러나 다른 사용자가 Error가 어디서 발생했는지 알기 어렵다는 문제가 있다.

▮ raise 구문

필요에 따라 강제로 Exception을 발생
내가 만든 function을 사용자는 어떻게 사용할 지 모르기 때문에 문제가 생겼을 경우 강제로 프로그램을 종료시켜줄 필요성이 있다.

raise <Exception Type>(예외 정보)

▮ assert 구문

특정 조건에 만족하지 않을 경우 예외 발생

assert 예외조건

 

File Handling

▮ 파일의 종류

파일의 종류는 text 파일과 binary 파일로 나뉜다.

  • text 파일 : 인간이 이해할 수 있는 형태인 문자열 형식으로 저장되어있다.
                         메모장으로 열었을 때 내용 확인이 가능한 파일
                         ex. HTML 파일, 파이썬 코드 파일
  • binary 파일 : 컴퓨터만 이해할 수 있는 형태인 이진 법형식으로 저장된 파일
                              메모장으로 열 경우 내용이 깨져 보인다.
                              엑셀파일, 워드 파일 같이 특정 어플리케이션에 종속된 파일

 

▮ File I/O

파이썬은 파일 처리를 위해 "open" 키워드를 사용한다.

f = open("<파일이름>", "접근모드") # "r" : 읽기모드, "w" : 쓰기모드, "a" : 내용추가모드
f.close()

 

with 구문과 함께 사용하면 close()를 해줄 필요가 없다.

 

읽기 모드 "r"

readlines() : 한줄 씩 불러와서 리스트 형태로 저장하고 싶을 경우 사용  (\n기준으로 분리)

readline() : 실행 시 마다 한줄 씩 읽어오기, 한번에 메모리에 올리기 너무 큰 파일의 경우 사용

 

쓰기 모드 "w"

추가 모드 "a"

▮ OS module

os 모듈을 사용하여 디렉토리를 다룰 수 있다.

 

디렉토리 생성

os.mkdir("<생성할폴더명>")

파일 이동 : shutill 라이브러리 사용

요즘은 pathlib 라이브러리를 사용 - Path를 객체로 사용

 

import os

if not os.path.isdir("log"):
    os.mkdir("log")
if not os.path.exists("log/count_log.txt"):
    with open("log/count_log.txt", "w", encoding="utf8") as f:
        f.write("--기록 시작--\n")

with open("log/count_log.txt", "a", encoding="utf8") as f:
    import random, datetime
    for i in range(1, 10):
        stamp = str(datetime.datetime.now())
        val = random.random() * 100000
        log_line = stamp + '\t' + str(val) + "값을 생성했습니다.\n"
        f.write(log_line)

▮ Pickle

객체는 메모리에 있어야 한다.

파이썬 인터프리터가 끝나면 메모리가 사라지기 때문에 파이썬의 객체를 영속화 하는 built-in 객체로 Pickle을 사용한다.

Pickle은 Python에 특화된 binary 파일이다.

 

class도 Pickle로 저장할 수 있다.

 

Logging Handling

프로그램이 실행되는 동안 일어나는 정보를 기록하는 것을 log라고 한다.

기록된 로그를 분석하여 의미 있는 결과를 도출할 수 있다.

▮ logging level

  • 프로그램 진행 상황에 따라 다른 Level의 Log를 출력할 필요가 있다.
  • DEBUG > INFO > WARNING > ERROR > CRITICAL
  • Log 관리 시 가장 기본이 되는 설정이다.
LEVEL 개요 example
debug 개발 시 처리 기록을 남겨야 하는 정보 - 다음 변수로 A를 호출함
- 변수 A를 B로 변경함
info 처리가 진행되는 동안의 정보를 알림 - 서버가 시작되었음
- 사용자 A가 프로그램에 접속함
- 서버가 종료됨
warning 사용자가 입력을 잘못 입력한 정보를 처리는 가능하나 원래 개발 시 의도치 않은 정보가 들어왔을 때 알림 - str 입력을 기대했으나 int가 입력됨
→ str로 변환 후 처리
error 잘못된 처리로 인해 에러가 났으나, 프로그램은 동작할 수 있음을 알림 - 파일에 기록을 해야하는데 파일이 없음
→ Exception 처리 후 사용자에게 알림
critical 잘못된 처리로 데이터의 손실이나 더이상 프로그램이 동작할 수 없음을 알림 - 잘못된 접근으로 해당 파일이 삭제됨
- 사용자에 의한 강제종료

▮ logging 모듈

python의 기본 log 관리 모듈

  • Python의 기본 logging level은 warning 부터 설정되어 있으므로 debug level부터 설정하기 위해서는 basicConfig가 필요하다.
import logging

if __name__=="__main__":
    logger = logging.getLogger("main")
    logging.basicConfig(level=logging.DEBUG)

    # log 파일 생성
    log_handler = logging.FileHandler("log_file", mode="w", encoding="utf8")
    logger.addHandler(log_handler)

    logging.debug("debug log")
    logging.info("info log")
    logging.warning("warning log")
    logging.error("error log")
    logging.critical("critical log")

 

이러한 설정을 해주는 방법이 두 가지가 있다.

  • configparser - 프로그램의 실행 설정을 파일에 저장
  • argparser - 실행 시점에

▮ configparser

  • 프로그램의 실행 설정을 file에 저장
  • Section, Key, Value 값의 형태로 설정된 설정 파일 사용
  • Dict Type 형태로 호출 후 사용
# example.cfg 파일

[SectionOne]
Status : Single
Name : Byeol
Age : 99

[SectionTwo]
FavoriteColor =Blue

[SectionThree]
FamilyName : Kim
import configparser

config = configparser.ConfigParser()

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

for key in config['SectionOne']:
    val = config['SectionOne'][key]
    print(f"{key} : {val}")
$ python configparser_ex.py 
['SectionOne', 'SectionTwo', 'SectionThree']
status : Single
name : Byeol   
age : 99

▮ argparser

argparser 정리 글

  • Console 창에서 프로그램 실행 시 Setting 정보를 저장
  • 거의 모든 Console 기반 Python 프로그램 기본으로 제공
  • Command-Line Option이라고 부름
import argparse

p = argparse.ArgumentParser(description="Sum two integers.")

p.add_argument('--a_val', help="A integers", type=int, required=True)
p.add_argument('--b_val', help="B integers", type=int, required=True)

args = p.parse_args()

print(args)
print(args.a_val)
print(args.b_val)
print(args.a_val + args.b_val)

위의 코드가 작성되어 있는 파일을 인자 값 없이 그냥 실행시키면 아래와 같이 출력된다.

$ python argparser_ex.py 
usage: argparser_ex.py [-h] -a A_VALUE -b B_VALUE
argparser_ex.py: error: the following arguments are required: -a/--a_value, -b/--b_value

인자값을 같이 입력해주면 결과가 출력된다.

$ python argparser_ex.py --a_val=10 --b_val=15
Namespace(a_val=10, b_val=15)
10
15
25

▮ Logging formatter

formatter = logging.Formatter('%(asctime)s %(levelname)s %(process)d $(message)s')

# Log config file
logging.config.fileConfig('logging.conf')
logger = logging.getLogger()
더보기

logging.conf

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args={sus.stdout,}

[formatter_simpleFormatter]
format=%(asctime)s %(levelname)s %(process)d $(message)s
datefmt=%m/%d/%Y %I:%M:%S %p

csv_writer.py

import logging
import logging.config
import csv

logging.config.fileConfig('logging.conf')
logger = logging.getLogger()

line_counter = 0
data_header = []
employee = []
customer_USA_only_list = []
customer = None

logger.info("Open file {0}".format("TEST",))
try:
    with open("customers.csv", "r") as customer_data:
        customer_reader = csv.reader(
            customer_data, delimiter=',', quotechar='"'
        )
        for custoemr in customer_reader:
            if customer[10].upper() == "USA":
                logger.info('ID {0} added'.format(custoemr[0],))
                customer_USA_only_list.append(customer)
except FileNotFoundError as e:
    logger.error('File Not found {0}'.format(e,))
    raise FileNotFoundError

logger.info('Write USA only data at {0}'.format("customer_USA_only.csv",))
with open("customers_USA_only.csv", "w") as custoemr_USA_only_csv:
    for customer in customer_USA_only_list:
        custoemr_USA_only_csv.write(",".join(custoemr).strip('\n')+"\n")

logger.info("Program Finished")

 

728x90