[문법] Python - 파일을 열고 닫는 방법 (txt, csv, json)

이우준·2023년 3월 28일
0

Python

목록 보기
1/3
post-custom-banner

파일 열기/닫기/변환하기

.txt 파일

코드가 속한 폴더에 함께 존재하는 .txt 파일을 불러오는 과정을 보자. 예를 들어 'saved_data.txt' 라는 파일을 불러오고 싶다면, 그 과정은 일반적으로 아래와 같다.

file = open('saved_data.txt')
contents = file.read()
file.close() # 파일을 닫아주는 라인

하지만 위와 같이 사용하는 경우 file을 닫아주는 과정을 깜빡할 수도 있는데, Python은 그런 상황을 방지하기 위해 아래와 같은 문법을 제공한다.

# 'saved_data.txt'를 'file' 이라는 이름의 변수로 다룸
with open('saved_data.txt') as file:
	contents = file.read()

만약 각 줄 단위로 불러와 list에 저장하여 사용하고 싶은 경우에는 아래와 같이 작성하면 된다.

contents = [] # line을 저장할 빈 list를 선언
with open('saved_data.txt') as file:
  for line in file:
    contents.append(line)

예시를 통해 보자. 'saved_data.txt' 파일이 Fig 1 과 같다고 생각해보자.

Fig 1. 'saved_data.txt' 예시
saved_data_football

위 .txt 파일에 대해 각 코드를 적용한 결과는 각각 아래와 같다.

with open('saved_data.txt') as file:
	contents = file.read()

print(contents)

# 아래와 같이 한번에 읽어오는 것을 알 수 있다.
'''
김민재,나폴리
손흥민,토트넘
이강인,마요르카
오현규,셀틱
황희찬,울버햄튼
이재성,마인츠
정우영,프라이부르크
황인범,올림피아코스
'''
contents = []
with open('saved_data.txt') as file:
  for line in file:
    contents.append(line)

print(contents)

'''
['김민재,나폴리\n', '손흥민,토트넘\n', '이강인,마요르카\n', '오현규,셀틱\n', '황희찬,울버햄튼\n', '이재성,마인츠\n', '정우영,프라이부르크\n', '황인범,올림피아코스']
'''

이때 바로 위의 출력 결과를 보면, '\n' 이라는 문자가 마지막에 추가되어 나온 것을 확인할 수 있다. 이는 Python이 .txt 파일에서 사용한 enter 키를 '\n' (=new line) 이라는 문자열로 인식하기 때문인데, '\t' (=tab) 이나 '\n'과 같은 공백을 제거해주는 strip() 을 적용하면 아래와 같이 깔끔하게 출력할 수 있다. strip() 은 단순히 공백만을 지우는 역할로 사용되는 것이 아니기 때문에, 더 많은 사용법은 이 링크를 참조해보자.

contents = []
with open('saved_data.txt') as file:
  for line in file:
    # .strip() 추가
    contents.append(line.strip())

print(contents)
'''
['김민재,나폴리', '손흥민,토트넘', '이강인,마요르카', '오현규,셀틱', '황희찬,울버햄튼', '이재성,마인츠', '정우영,프라이부르크', '황인범,올림피아코스']
'''

.csv 파일

CSV는 Comma Separated Value 라는 뜻으로, 직역하면 comma로 구분된 값이다. (사실 구분 문자 즉, delimiter는 꼭 comma가 아니어도 된다.) 이때, 담겨진 정보는 각각의 열로 구분된다.
참고로 별도의 key 저장 없이 value들만 저장된다는 특징 때문에 용량이 작다는 장점이 있다.

Q. 그나저나 comma로 구분하면, data에 직접 comma가 들어가있는 경우는 어떻게 처리할 수 있을까?
A. 큰 따옴표("")로 data를 감싸서 열을 구분한다.

CSV 파일을 다루기 위해서는 csv package를 import 해야 된다. 아래의 예시 코드를 보자.

import csv

# 몇 번째 row를 읽을 것인지 결정하는 변수 'row_index'
row_index = 2

with open('saved_data.csv') as file:
  # 쉼표 (',')로 구분하여 파일을 읽겠다는 뜻
  csv_data = csv.reader(file, delimiter = ',')
    for row in csv_data:
      # 이 코드에서는 두 번째 열을 읽는 것으로 적용됨
      print(row[row_index])

.json 파일

JSON은 JavaScript Object Notation의 약자로, 웹 환경 (서버나 브라우저 등)에서 데이터를 주고 받을 때 가장 널리 사용되는 데이터 형식이다.
Python의 dictionary처럼 key와 value를 가지고 있는데, 이로 인해 원하는 value를 빠르게 찾을 수 있다는 장점이 있다. 하지만 다른 format들에 비해 용량이 크다는 단점도 있다.

JSON \leftrightarrow Dictionary (Python)

전체적인 구조가 비슷해서 그런지, JSON을 dictionary 형태로 바꿔 사용할 수도 있다. (물론, 반대도 가능)
Python에서는 json package의 .loads() (JSON to Dict) 와 .dumps() (Dict to JSON)를 사용하여 이 둘을 변환할 수 있는데, 유의할 점은 .loads() 적용시 dictionary의 모든 원소가 string으로 설정된다는 것이다.

참고로 .loads()는 load + string 이라는 뜻

JSON 파일을 다루기 위해서도 package를 import 해야 하는데, 아래는 dictionary와 서로 변환되는 함수에 대한 예시 코드이다.

import json

# 가지고 있는 source 파일
src = 'attendance.json'

# JSON -> Dictionary
def json_to_dict(file_name):
  with open(file_name) as file:
    json_data = file.read() # 전체를 한번에 읽어옴
    return json.loads(json_data) # json을 dictionary로 변환

# Dictionary -> JSON
def dict_to_json(dict, file_name):
  # 'w'를 두 번째 인자로 넣어 쓰기 모드를 사용할 수 있다
  # Default: 'r' (read mode)
  with open(file_name, 'w') as file:
    json_data = json.dumps(dict)
    file.write(json_data)

# 적용 코드
created_dict = json_to_dict(src)
# 새로 작성할 json 파일 ('another.json')
dict_to_json(created_dict, 'another.json')

.csv \rightarrow .json

용량이 늘어나기는 하지만 때때로 .csv 파일을 .json으로 변환해야 할 때가 있는데, 아래 코드를 통해 그 방법을 알아보자.

# CSV, JSON package를 모두 import
import csv
import json

def csv_to_json(from_csv, to_json):
  # 먼저 .csv를 dictionary 형식으로 바꾼다
  attendances = [] # dictionary들이 담길 list
  with open(from_csv) as src:
    csv_data = csv.reader(src)
    for row in csv_data:
      # 출석에 대한 정보를 담은 dictionary를 생성
      # 각 열에 "name", "age", "class" 정보가 있었다고 가정
      attendance = {
      "name": row[0],
      "age": int(row[1]), # age 등의 정보는 int로 변환
      "class": row[2]      
      }
      attendances.append(attendance) # List에 append
      
  # .json 으로 작성할 것이니 'w' (write mode)
  with open(to_json, 'w') as dst:
    # 위에 언급한 .dumps() 대신 .dump()로 한번에 처리할 수도 있다. 
    json.dump(attendances, dst)

# Source, Destination 선언
src = 'attendance.csv'
dst = 'attendance.json'

# src (.csv) -> dst (.json) 로 파일 변환
csv_to_json(src, dst)

Reference

.strip() 사용 링크: https://wikidocs.net/33017

post-custom-banner

0개의 댓글