File / Exception / Log Handling
예외처리란?
예외 처리는 프로그램을 개발하며 반드시 신경써야하는 부분이다. 사전에 인지할 수 있는 예외에 대해서는 명시적으로 정의하여 처리해야 한다. 예상이 불가능한 예외에 대해서는 해당 상황에 대한 대처방안을 마련해야 한다. 인터프리터에 의해 프로그램이 바로 중단되지 않도록 대처를 해야하며, 이를 Exception Handling이라 한다.
Python Exception Handling Example
Python에서는 if
문을 통해 예상 가능한 예외를 처리할 수 있으나, try ~ except
문법을 사용하기를 권장한다. 예시는 아래와 같다.
# try ~ except ~ else ~ finally example
lst = [1, 2, 3]
for i in range(5) :
try :
lst[i]
except IndexError :
print("run except block")
print(e)
else :
print("run else block")
print("i :", lst[i])
finally :
print("run final block\n")
# output
'''
run else block
i : 1
run final block
run else block
i : 2
run final block
run else block
i : 3
run final block
run except block
list index out of range
run final block
run except block
list index out of range
run final block
'''
강제 예외 발생
raise
와 assert
를 통해 특정 조건에 부합하지 않는 경우 강제로 Exception을 발생시킬 수 있다.
# raise excample
value = input("정수를 입력하세요.")
if not value.isdigit() :
raise ValueError("정수가 아닙니다.")
# output
'''
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError: 정수가 아닙니다.
'''
# assert example
value = input("정수를 입력하세요.")
assert isinstance(value, int)
# output
'''
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
'''
File Handling
먼저, File은 Text File과 Binary File로 구분된다.Binary File은 사람이 읽을 수 없는 형태이며, 특정 Application을 통해서만 read 할 수 있다. (ex. Excel
, Word
등)
Text File은 메모장
등을 통해 read 할 수 있는, 문자열 형식으로 저장된 기본적인 파일을 의미한다.(ex. .txt file
, .py file
등)
최종적으로 컴퓨터는 이 Text File 조차도 Binary 파일로 변환하여 실행한다. (ex. .pyc file
등)
Python File I/O
Python에서 File을 입출력하는 기본 문법은 open
함수이다. parameter의 첫 번째에는 경로를 포함한 파일명을 입력하고, 두 번째에는 'r'
혹은 'rb'
로 값을 전달한다.
이렇게 열린 File은 메모리에 올라온 상태가 되므로, 사용이 종료되면 close
로 닫아주어야 메모리 누수가 생기지 않는다.
이는 with
block을 통해 쉽게 사용할 수 있다. 블록이 끝나는 순간 File object는 파괴된다.
open
한 파일 객체은 File 객체의 readlines()
, readline()
, read()
와 같은 메서드를 통해 내부의 정보를 활용할 수 있다. read()
는 모든 문자열을 str
type으로 반환하며, readlines()
는 list
type으로 반환한다. readline()
은 한 줄씩 str
type으로 반환한다.
# read() example
f = open("file_name.txt", "r")
contents = f.read()
print(type(contents)) # <class 'str'>
f.close
# with and readlines() example
with open("file_name.txt", "r") as f :
contents = f.readlines() # <class 'list'>
print(type(contents))
# readline() example
with open("file_name.txt", "r") as f :
while True :
line = f.readline() # <class 'str'>
for word in line.split() :
print(word) # word가 출력됨.
if not line :
break
File을 쓰기 위해서는 'w'
, 'wb'
, 'a'
, 'ab'
모드로 open
한다. w
는 File의 기존 값을 없애고 덮어씌우는 개념이며, a
는 File의 뒤에 이어쓰는 개념이다.
open
에는 encoding
parameter가 있으며, 'utf8'
과 'CP949'
와 같은 값을 전달한다. utf8
은 다국어 문자를 지원하는 체계로 가장 보변적으로 사용되고 있으며, CP949
는 windows의 기본 encoding 체계이다.
# 'w' mode example
f = open("new_file_name.txt", "w", encoding="utf8")
for i in range(1,11) :
data = f.'{i}번째 줄입니다.\n'
f.write(data)
f.close
# 'a' mode example
with open("new_file_name.txt", "a", encoding="utf8") as f :
for i in range(11, 20) :
data = f.'{i}번째 줄입니다.\n'
f.write(data)
Python Directory Handling
os
모듈과 pathlib
모듈을 통해 Directory를 관리할 수 있다. os
모듈은 path
와 같은 Field의 값을 str
로 반환하나, pathlib
은 path
객체를 반환하여 더 다양하게 사용할 수 있다.
# os module example
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) + "값이 생성되었습니다"
f.write(log_line)
# pathlib module example
import pathlib
cwd = pathlib.Path.cwd()
print(cwd.parent) # 부모의 디렉토리 정보가 출력됨.
print(cwd.parents) # 모든 부모의 디렉토리 정보가 출력됨.
print(cwd.glob) # 디렉토리 내의 모든 파일 정보가 출력됨.
Pickle
Python이 실행되는 동안의 객체는 메모리에 올라와 있는 상태이며, 프로그램이 종료하면 동시에 메모리에서 삭제된다. 이를 영속화 시키기 위해 사용하는 것이 pickle
이다. .pickle
로 저장되는 File은 Binary File이다.
# pickle module example
import pickle
f = open("list.pickle", "wb")
test = [1,2,3,4,5]
pickle.dump(test, f) # test 객체가 list.pickle file에 저장됨.
f.close()
f = open("list.pickle", "rb")
another = pickle.load(f) # list.pickle에 있던 객체가 another에 할당됨.
f.close()
Log Handling
프로그램이 실행되는 동안 일어나는 정보를 기록하는 것을 의미한다. 해당 기록을 분석하기 위해서는 File로 저장해야 한다. 이를 위해 Python은 logging
모듈을 제공한다.
logging
의 메서드는 기본적으로 Console에만 출력을 해주며, default 설정으로는 warning부터 메세지가 출력된다. basicConfig()
나 setLevel()
등의 메서드를 통해 설정을 변경할 수 있다.
FileHandler()
와 addHandler()
메서드를 사용해 Log를 File에 기록할 수 있다.
# logging module example
import logging
logging.debug('level 1')
logging.info('level 2')
logging.warning('level 3') # default 설정으로 여기서부터 출력됨.
logging.error('level 4')
logging.critical('level 5')
# basicConfig() example
logging.basicConfig(level = logging.DEBUG)
logging.debug('now print this')
# setLevel() example
logger = logging.getLogger("main")
logger.setLevel(logging.INFO)
logging.debug('now do not print this') # 설정에 의해 출력되지 않음.
# file write example
file = logging.FileHandler('thisIsFile.log', mode='w', enscoding='utf8')
logger.addHandler(file) # log가 file에 저장됨.
Program Setting
실제 프로그램을 운영하기 위해선 여러 설정이 필요하다. 데이터 파일의 위치나, 파일 저장 장소 등의 정보를 설정해줄 방법이 필요한 것이다.
이를 위해 configparser
와 argparser
가 있다. configparser
는 파일에 해당 정보를 저장하는 것이고, argparser
는 실행 시점에 해당 정보를 전달하는 방식이다. 이에 대한 내용은 개인학습에서 다루겠다.
이렇게 설정된 파일은 Log의 설정으로 쓰일 수 있으며, Formatting을 통해 출력 혹은 저장될 수 있다.
# log config file example
import logging
logging.config.fileConfig('logging.conf')
logger = logging.getLogger()
# logging formater example
formatter = logging.Formatter(f'{time} {levelname} {provess} {message})
Python data handling
CSV
필드를 Comma로 구분한 Text File이다. 엑셀과 비슷한 양식의 데이터이며, 프로그램에 상관없이 쓸 수 있는 Text 형태의 File이다.
open
함수를 통해 해당 File을 읽을수도 있으며, csv
module을 통해 이를 객체 형태로 사용할수도 있다.
# open example
with open('file_name.csv') as f :
while True :
line = f.readline()
if not line :
break
print(line.split(','))
# csv example
import csv
with open('file_name.csv') as f :
csv_data = csv.reader(f)
for row in csv_data :
print(row)
HTML과 XML
Web에서 정보를 구조적으로 표현하기 위한 언어이다. Tag를 통해 요소를 구분하며, 트리형태의 포함관계를 가진다. Web에 표현되는 정보는 Browser가 HTML을 해석하여 표시한 결과이다. XML도 HTML과 비슷하며, 다른 기종 간 정보를 주고받기에 유용한 저장방식이다. 마찬가지로 Tag로 구분되며, 구조적인 정보를 표현한다. 두 데이터 형식 모두 Text로 구성된 Mark Up Language이다. 즉, Web의 모든 정보는 Text로 구성되어 있다는 의미이며, 이 구조를 이해하면 모든 정보를 활용할 수 있다.
Regular Expression
정규표현식이란, 복잡한 문자열 패턴을 정의하는 문자표현 공식을 의미한다. 이를 통해 특정한 규칙을 가진 문자열의 집합을 추출할 수 있다.
HTML도 Tag를 통한 일정한 형식이 존재하기 때문에, 이를 활용하면 Web의 모든 정보를 활용할 수 있다.
정규식은 규칙이 매우 방대하기 때문에, 활용 시점마다 찾아보고 공부하는 것을 추천한다. 이때 유용한 도구는 '정규식 연습장'이다. (Link)
Python은 re
module을 제공하며 이를 통해 정규표현식을 사용할 수 있다. Web으로부터의 정보는 urllib
모듈의 request.urlopen()
을 통해 불러올 수 있다.
# urllib and re example
import urllib.request
import re
url = 'https://www.naver.com/'
html = urllib.reqeust.urlopen(url)
html_contents = str(html.read().decode('utf8'))
lotto_num = re.findall("\<dl class=\'blind\'\>([/s/S]+?)(\<dl\>)", html_contents)
print(lotto_num)
BeautifulSoup
정규표현식을 통해 문자열을 parsing 하는 방법도 있으나, beautifulsoup
모듈을 통해 parsing을 할 수 있다. 속도는 상대적으로 느리나, 간편하다는 장점이 있다.
이는 외부 모듈이며, 내부적으로 lxml
이나 html5lib
과 같은 다른 라이브러리에 의존적이다.
# beautifulsoup example
from bs4 import BeautifulSoup
with open("books.xml", "r", encoding="utf8") as books_file:
books_xml = books_file.read()
soup = BeautifulSoup(books_xml, "lxml")
for book_info in soup.find_all("author"): # tag 가 'author'인 모든 정보
print(book_info)
print(book_info.get_text()) # 태그와 태그 사이의 값
JSON
JavaScript Object Notation의 줄임말로, 원래는 Javascript의 데이터 객체 표현 방식이다. 많은 장점으로 인해 대표적인 데이터 형태로 자리잡았다.
현재는 웹에서 제공하는 대부분의 API가 JSON을 활용하고 있다.JSON은 key : value 쌍으로 구성 되어 있어, Dict type의 객체와 유사하게 접근하여 사용할 수 있다. json
모듈이 있으며, json 객체도 Dict type이다.
# json file read example
import json
with open('json_file.json', 'r', encoding='utf8') as f :
contents = f.read()
json_data = json.loads(contents) # dict type object
print(json_data.items())
# json file write example
import json
dict_data = {'Name:Jack', 'Age':29, 'Sex':'Male'}
with open('new_json.json', 'w') as f :
json.dump(dict_data, f)
과제
- Baseball
- Morsecode
isdigit() and isdecimal()
isdigit()
은 3^2와 같은 모양의 문자열도 True를 반환한다. 만약 0~9까지의 숫자를 원하는 logic이라면, isdecimal()
을 활용하는 것이 좋을 것 같다.
다중 조건 check기법
다양한 방법이 제시되었다. 예시는 아래와 같다.
# all
all(condition1(), condition2(), condition3())
# &=
result = True
result &= condition1()
result &= condition2()
result &= condition3()
# sum
sum((condition1(), condition2(), condition3())) == 3
nonlocal keyword
global
과 local
중간의 느낌으로, 감싸고 있는 가까운 함수의 scope에 접근한다.
# nonlocal example
def outter(outter_var) :
def inner() :
nonlocal outter_var
outter_var += 1
return
return
is_yes()
input_str.lower() in ['y', 'yes']
과 같은 형태로 표현할 수 있다.
unittest
pycharm에서 unittest
Module을 활용해 test를 수행할 수 있다.
Morsecode 판별
len(set(user_input)-{-. }) > 0
와 같이 차집합 연산으로 확인하는 방법이 있었다.
Nested List Comprehension
중첩 List Comprehension으로 word 단위끼리 조합하고, 이후에 문장을 만드는 방법이 있었다.
정규표현식 사용
re.findall('[A-Za-z.!?]', input_str)
으로 확인하고, 불필요한 문장부호는 re.sub('[.,!?]', '', input_str)
로 지우는 방법이 있었다.
개인 학습
- Logging
- ConfigParser
- ArgParser
Logging Module
Python에서 제공하는 logging Module에 대해 알아보았다. 다음 링크에서 많은 도움을 받았다. (Link)
logging work flow
logging의 work flow는 다음과 같다.
- Logger : 어플리케이션 코드가 직접 사용할 수 있는 인터페이스
- Handler : logger에 의해 만들어진 log를 적합한 위치로 전달
- Filter : 어떤 log가 출력되어야 하는지 결정
- Formatter : log 기록의 최종 출력본 레이아웃을 결정
먼저, Logger Class의 Instance를 생성한다. 이때 logger는 name을 가지며, logger는 다른 인스턴스와 계층적 관계를 가진다. 이후, Handler를 통해 log를 어디에 기록할지 설정한다. Filter는 level보다 복잡한 필터링을 원할 때 사용할 수 있다. 마지막으로, Formatter는 출력되는 형식을 결정한다.
# logger example
import logging
logger = logging.getLogger('name') # name을 설정하지 않는 경우 'root'
logger.setLevel(logging.INFO)
logger.info('Message')
# handler example
stream_handler = logging.StreamHandler()
file_handler = logging.FileHandler(filename = 'infomation.log')
# formatter example
formatter = logging.Formatter(fmt=f"{asctime} - {name} - {levelname} - {message}")
# handler setting
stream_handler.setLevel(logging.INFO)
stream_handler.setFormatter(formatter) # console에는 info부터 출력
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(fotmatter) # file에는 debug부터 출력
Config Parser란?
Python에서 제공하는 configparser
module은 설정 정보를 file형태로 손쉽게 입출력할 수 있게 한다. 기본적으로 Dict type의 형태로 구성되어 있으며, I/O가 손쉽다. 다음 링크에서 많은 도움을 받았다. (Link)
configparser 예시
configparser
를 통해 file을 생성하고, 읽어오는 예시이다.
# create config file example
from configparser import ConfigParser
config = ConfigParser() # Dict type object
config['settings'] = {
'debug': 'true',
'secret_key': 'abc123',
'log_path': '/my_app/log'
}
config['db'] = {
'db_name': 'myapp_dev',
'db_host': 'localhost',
'db_port': '8889'
}
config['files'] = {
'use_cdn': 'false',
'images_path': '/my_app/images'
}
with open('./dev.ini', 'w') as f:
config.write(f) # 'dev.ini' file creadted
# read config file example
from configparser import ConfigParser
parser = ConfigParser()
parser.read('dev.ini')
print(parser.sections()) # ['settings', 'db', 'files']
print(parser.options('settings')) # ['debug', 'secret_key', 'log_path']
print(parser.get('settings', 'secret_key')) # abc123
ArgParser란?
Python에서는 CLI 환경에서 주어지는 input variable을 처리할 수 있도록 argparser
Module을 제공한다. 해당 모듈을 통해 프로그램이 실행될 때 여러 설정을 조절할 수 있다.
argparser 예시
argparser
Module의 사용 예시이다.
# argparser example
import argparse
def main():
parser = argparse.ArgumentParser()
parser.add_argument('X', type=int,
help="What is the first number?")
parser.add_argument('Y', type=int,
help="What is the second number?")
args = parser.parse_args()
X = args.X
Y = args.Y
print("%d + %d = %d" % (X, Y, X+Y))
if __name__=="__main__":
main()
'네이버 부스트캠프 AI Tech' 카테고리의 다른 글
[U] Day 07 - 경사하강법 (0) | 2021.03.25 |
---|---|
[U] Day 06 - Numpy / 벡터 / 행렬 (0) | 2021.03.25 |
[U] Day 04 - 파이썬 기초 문법 III (0) | 2021.03.25 |
[U] Day 03 - 파이썬 기초 문법 II (0) | 2021.03.25 |
[U] Day 02 - 파이썬 기초 문법 (0) | 2021.03.25 |
Uploaded by Notion2Tistory v1.1.0