이번 강의에서는 프로그램을 보다 견고하게 만들어주는 예외 처리와 파일 다루기에 대해서 배웁니다.
개발 시, 다양한 상황에서 예상치 못한 오류가 발생합니다. 이를 해결하고 방지하기 위해서 사전에 오류가 발생할 수 있는 예외를 포괄적으로 지정해서 대비하게 됩니다. 또 프로그램을 개발할 때에는, 앞서 소개한 여러 모듈 및 파일과 폴더를 사용하는 경우가 많기 때문에 유동적으로 파일과 디렉토리를 다루는 것에 대해 알아두어야 합니다.
추가적으로 프로그램을 진행하면서 진행 상황 및 이슈를 기록하는 로깅(logging)에 대해서 배웁니다. 로그 데이터를 남기는 것은 데이터 기반의 애플리케이션 개발에서 매우 중요합니다. 로그 데이터를 보다 구조적으로 설계하는 것이 하나의 분야로 자리잡고 매우 중요한 부분으로 여겨지기 때문에 익숙해지는 것이 좋습니다.
복잡한 프로그램을 개발할수록, 예상할 수 없는 예외가 발생하기 마련입니다. 당연히 모든 예외 사항을 예측하여 오류와 에러를 방지하는 것이 최선의 방법이지만, 현실적으로 불가능합니다.
그렇기 때문에, 예외가 발생할 수 있는 부분 혹은 전체 시스템에서 예외가 발생할 수 있음을 가정하여, 그 부분에 예외 처리를 하고 기록함으로써 프로그램을 개선시키는 것이 중요합니다. 더욱 치밀하고 견고하게 예외 처리를 할수록 프로그램 동작에 이상이 없고 개선할 수 있는 여지도 충분히 갖출 수 있습니다.
try:
예외 발생 가능 코드
except <Exception Type> as e: # 어떤 내용의 exception이 발생했는지 볼 수 있음
예외 발생 시, 대응 코드
Exception | Description |
---|---|
IndexError | List의 index가 존재하지 않을 때 |
NameError | 존재하지 않은 변수를 호출 할 때 |
ZeroDivisionError | 0으로 숫자를 나눌 때 |
ValueError | 변환할 수 없는 문자/숫자를 변환할 때 |
FileNotFoundError | 존재하지 않는 파일을 호출할 때 |
try:
예외 발생 가능 코드
except:
예외 발생 시, 대응 코드
else: # 그러나 if~else문은 로직 문제일 때 사용하는 것이 좋음
예외가 발생하지 않을 때 실행 코드
finally:
마지막에 무조건 실행하는 코드
raise <Exception Type>(예외정보)
while True:
value = input('숫자를 입력해주세요:')
for digit in value:
raise ValueError('숫자값이 아닙니다.')
assert 예외조건
a = int
b = input()
assert a == type(b)
-> True or False
Binary 파일 | Text 파일 |
---|---|
컴퓨터만 해석할 수 있는 이진 형식으로 저장된 파일 | 시각적으로 해석 가능한 형식으로 저장된 파일 |
파일을 열면 깨지는 현상 발생 | 내용 확인 가능 |
엑셀, 워드 파일 | txt, html, py 파일 |
접근 모드 | Description |
---|---|
r | 읽기모드 - 파일을 읽기만 할 때 사용(default) |
w | 쓰기모드 - 파일에 내용을 쓸 때 사용 |
a | 추가모드 - 새로운 내용을 추가 시킬 때 사용 |
# introduction.txt 파일
Hi My name is Carvin.
I'm 27 years old.
I really want to be a recommendation system developer.
So, I have been studying Deep learning and Data engineering.
with open('introduction.txt', 'r') as f:
files = f.read()
-> b"Hi My name is Carvin.\nI'm 27 years old.\nI really want to be a recommendation system developer.\nSo, I have been studying Deep learning and Data engineering."
files = f.readlines() # 파일 전체를 list로 반환
-> [b'Hi My name is Carvin.\n',
b"I'm 27 years old.\n",
b'I really want to be a recommendation system developer.\n',
b'So, I have been studying Deep learning and Data engineering.']
files = f.readline() # 파일 중 한줄씩 읽기
-> b'Hi My name is Carvin.\n'
f = open('*.txt', 'w', encoding = 'utf8')
for i in range(1, 11):
data = f'{i}번째 줄입니다.\n'
f.write(data)
f.close()
with open('*.txt', 'a', encoding = 'utf8') as f: # mode = 'a'는 update 모드
for i in range(1, 11):
data = f'{i}번째 줄입니다.\n'
f.write(data)
os 모듈은 Operating System의 약자로서 운영체제에서 제공되는 여러 기능을 python에서 수행 가능하게 합니다.
method | Description |
---|---|
getcwd() | 현재 작업 dir 확인 |
mkdir(name) | 현재 dir에서 name 폴더 생성 |
listdir(dir) | 해당 dir의 파일 조회(ls) |
path.exists(dir) | 해당 dir의 파일 존재 여부 |
path.join('', '') | 경로 만들어주기 |
❗️persistence, 영속성이란 ‘영원히 계속되는 성질이나 능력’을 의미하며, 당시 상태를 그대로 저장한다는 것을 의미한다고 생각함
파일을 읽고 쓰고하는 과정에서 항상 같은 폴더 디렉토리의 파일만을 다룰 수는 없습니다. 프로그램을 개발하거나 프로젝트를 하게 되면 다양한 디렉토리의 파일을 참고하게 되는데, 이 때 python에서는 다른 디렉토리의 파일을 참고할 수 있도록 기능을 제공하고 있습니다.
Folder
├── file1.txt
├── folder1
│ └── file2.txt
├── folder2
│ ├── file3.txt
│ └── file4.jpg
└── folder3
├── file5.txt
├── file6.jpg
└── folder4
├── text2.jpg
├── text3.jpg
└── test.ipynb <- 현재 jupyter notebook 실행 디렉토리
os 모듈
python에서 기본적으로 제공하는 모듈 중에서 os 모듈은, operation system(운영체제)와 관련된 모듈로 디렉토리 및 경로와 파일 등에서 활용할 수 있습니다. 출처
import os
os.listdir() # 해당 디렉토리(folder4)의 파일을 모두 list로 반환
-> ['text2.jpg', 'text3,.jpg', 'test.ipynb']
path = os.path.join('..', '..') # 상위 상위 폴더인 Folder
os.listdir(path) # 상위 상위 폴더인 Folder의 파일을 모두 list로 반환
-> ['file1.txt', 'folder1', 'folder2', 'folder3']
glob 모듈
glob 모듈은 Unix shell이 사용하는 규칙에 따라 지정된 패턴과 일치하는 모든 경로를 찾아줍니다. os.listdir()과 똑같다고 생각할 수 있지만 os.listdir()는 해당 디렉토리의 항목(파일 및 폴더)들을 반환해준다면 glob은 경로명을 반환해준다는 차이가 있습니다. 출처
import glob
glob.glob('*') # 해당 디렉토리(folder4)의 경로를 모두 list로 반환
-> ['text2.jpg', 'text3,.jpg', 'test.ipynb']
# os.listdir()과 차이가 발생하지 않는 이유는 현재 디렉토리에서 작업하고 있기 때문에 상대경로가 파일이름으로 동일하기 때문
glob.glob('*.ipynb') # 해당 디렉토리(folder4)의 ipynb 파일의 경로를 모두 반환
-> ['test.ipynb']
path = os.path.join('..', '..', '*') # 상위 상위 폴더인 Folder
glob.glob(path) # 상위 상위 폴더인 Folder의 파일 경로를 모두 list로 반환
-> ['../../file1.txt', '../../folder1', '../../folder2', '../../folder3']
path = os.path.join('..', '..', '*.txt') # 상위 상위 폴더인 Folder
glob.glob(path) # 상위 상위 폴더인 Folder의 txt 파일 경로를 모두 list로 반환
-> ['../../file1.txt']
log, 로그란 시스템의 기록을 담고 있는 데이터를 의미합니다. 이러한 데이터에는 성능, 오류, 경고 및 운영 정보 등의 중요 정보가 기록되며, 특별한 형태의 기준에 따라 숫자와 기호 등으로 이루어져 있습니다.
python에서는 log를 추적하고 기록하기 위해 logging 모듈을 제공하고 있습니다. logging은 어떤 소프트웨어가 실행될 때 발생하는 이벤트를 추적하는 수단입니다. 소프트웨어 개발자는 코드에 logging 호출을 추가하여 특정 이벤트가 발생했음을 나타내고 확인할 수 있습니다.
logging 모듈
import logging
if __name__ == '__main__':
logger = logging.getLogger('main')
logging.basicConfig(level = logging.DEBUG) # DEBUG로 logging level 하향 조정
logger.setLevel(logging.INFO)
# logging 출력 (my_log 파일로 쓰기)
steam_handler = logging.FileHander(
'my_log', mode = 'w', encoding = 'utf8')
logger.addHandler(steam_handler)
configparser
argparser
import argparse
args = argparse.ArgumentParser(description='Argparse Tutorial')
args.add_argument(
dest = '--name', # 해당 객체
default = '', # 기본값
type = int, # 인자 type
required = True, # 필요성 여부
help='an integer for printing repeatably' # help 시 설명
)
이번 강의에서는 python을 통해 데이터 분석에서 가장 많이 다루는 csv, web, XML, JSON이라는 네 가지 데이터 형식에 대해서 배웁니다.
CSV 파일 포맷은 어떠한 프로그래밍 언어든 데이터를 다루는 분야에서 가장 기본이 되는 형식입니다. 보통 엑셀의 텍스트 데이터 형식을 CSV로 이해할 수 있습니다. 데이터프레임으로 다루기 편하며 데이터 분석 및 python에서 매우 중요한 데이터 타입으로 핸들링하는 것에 익숙해지는 것이 필요합니다.
웹은 인터넷 공간을 의미하며 많은 정보를 제공하고 있습니다. 그렇기 때문에 웹 상에 존재하는 데이터를 통해서 다양한 분석을 할 수 있습니다. 웹 상에 존재하는 데이터를 얻기 위해서는 웹을 표현하는 가장 기본적인 언어인 HTML과 데이터를 가져올 수 있는 크롤링 기술이 있습니다. 특히, 웹 상 존재하는 raw한 데이터를 전처리하기 위해 정규표현식(regex)를 학습함으로써 데이터를 보다 빠르고 정확하게 처리할 수 있습니다.
마지막으로 데이터를 저장하는 다양한 포맷 중 XML(eXtensible Markup Languages)과 JSON(JavaScript Object Notation)이 있습니다.
XML은 프로그래밍 언어에서 데이터를 저장하고 불러오는 전통적인 파일 포맷으로, 흔히 레거시 시스템(오래전에 구축된 시스템)에서 raw파일을 저장하는 대표적인 포맷입니다. JSON은 이와 달리 모바일 환경이 발전하면서 사용되기 시작된 저장 포맷으로, 웹에서 많이 사용되는 JavaScript의 문법을 활용하여 저장하는 포맷입니다.
import csv
reader = csv.reader(
f,
delimiter = ',', # 구분자
quotechar = '"', # 문자열을 둘러쌓는 신호 문자
lineterminator = '', # 줄 구분자
quoting = csv.QUOTE_ALL # quotechar 레벨 지정
)
<title> Hello, World </title> #제목 요소, 값은 Hello, World
<!doctype html>
<html>
<head>
<title>Hello HTML</title>
</head>
<body>
<p>Hello World!</p>
</body>
method | Description |
---|---|
match(pattern, string) | pattern으로 시작하는 string을 return |
search(pattern, string) | pattern이 존재하는 string을 return |
findall(pattern, string) | string에 존재하는 pattern을 return |
fullmatch(pattern, string | 정확하게 pattern과 일치하는 string을 return |
sub(pattern, repl, string) | string에 존재하는 pattern을 repl로 변경 |
<?xml version="1.0"?>
<고양이>
<이름>나비</이름>
<품종>샴</품종>
<나이>6</나이>
<중성화>예</중성화>
<발톱 제거>아니요</발톱 제거>
<등록 번호>Izz138bod</등록 번호>
<소유자>이강주</소유자>
</고양이>