6. Exception/File/Log handling
- -
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
- 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")
'부스트캠프 AI Tech 4기' 카테고리의 다른 글
8. 벡터와 행렬 (1) | 2022.09.23 |
---|---|
7. Pandas (1) | 2022.09.23 |
5. Python data handling (0) | 2022.09.23 |
5. Numpy (0) | 2022.09.23 |
4. Module and Project/가상환경 (2) | 2022.09.21 |