← 파이썬 강의 목록으로
⚙️
중급 (Intermediate)
with open · csv · json · encoding utf-8

6주차 — 파일 입출력 (텍스트·CSV·JSON)

with open 으로 안전하게 텍스트 파일 읽고 쓰기, csv 모듈로 표 형식 데이터 처리, json 으로 구조화 데이터 직렬화·역직렬화를 익힙니다.

filecsvjsonencoding
소요 시간
2시간
난이도
📊 중급
선수 조건
🎯 5주차
결과물
메모장·CSV 통계·JSON 영구 저장 도구

이 강의에서 배우는 것

  • 1텍스트 파일을 with open 으로 안전하게 다룬다
  • 2CSV 파일을 csv 모듈로 읽고 쓴다
  • 3JSON으로 구조화된 데이터를 저장·로드한다

1. 텍스트 파일 — with 문

파일을 자동으로 닫아줍니다.

python
# 쓰기
with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("첫 줄\n")
    f.writelines(["A\n", "B\n", "C\n"])

# 읽기
with open("notes.txt", encoding="utf-8") as f:
    content = f.read()      # 전체 한 번에
    # 또는
    for line in f:           # 한 줄씩
        print(line.rstrip())

모드

모드의미
r읽기 (기본)
w쓰기 (기존 내용 삭제)
a추가
r+읽기/쓰기
b바이너리 (예: rb, wb)
⚠️

항상 encoding="utf-8" 명시 (한글 안전).

2. CSV

쉼표로 구분된 표 형식.

python
import csv

# 쓰기
with open("scores.csv", "w", encoding="utf-8", newline="") as f:
    w = csv.writer(f)
    w.writerow(["name", "score"])
    w.writerows([["Alice", 92], ["Bob", 78]])

# 읽기
with open("scores.csv", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        print(row["name"], row["score"])
⚠️

newline="" 빠뜨리면 빈 줄 생김 (Windows).

3. JSON

구조화된 데이터를 텍스트로 직렬화.

python
import json

data = {
    "name": "홍길동",
    "skills": ["Python", "SQL"],
    "active": True,
}

# 저장
with open("profile.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# 로드
with open("profile.json", encoding="utf-8") as f:
    loaded = json.load(f)
print(loaded["skills"])
  • ensure_ascii=False — 한글을 그대로
  • indent=2 — 사람이 읽기 쉽게 들여쓰기

4. 자주 하는 실수

  1. open 후 close 누락 — with 사용으로 자동 처리
  2. encoding 누락 — Windows에서 한글 깨짐
  3. json.dump vs json.dumps — dump 는 파일에, dumps 는 문자열로
  4. CSV newline="" 누락 — Windows에서 빈 줄 추가됨
  5. JSON으로 저장 안 되는 타입 — datetime, 사용자 클래스. 변환 필요

5. FAQ

Q1. CSV 와 JSON 중 뭘 쓰나요?

표 형태 데이터는 CSV, 중첩·구조화 데이터는 JSON.

Q2. 큰 파일도 한 번에 읽어도 되나요?

메모리에 올라가므로 GB 단위는 위험. 라인 단위 순회 또는 제너레이터 사용.

Q3. pickle 은 뭔가요?

파이썬 객체를 그대로 저장. 단, 다른 언어에서 못 읽고 보안 위험. JSON 권장.

💻 예제 (examples)

실제로 실행해 결과를 확인할 수 있는 예제 코드입니다.

01_text.py텍스트 파일 읽기/쓰기
CODE
# 쓰기
with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("첫 줄\n")
    f.writelines(["A\n", "B\n", "C\n"])

# 읽기 (한 줄씩)
with open("notes.txt", encoding="utf-8") as f:
    for line in f:
        print(line.rstrip())
▶ 실행 결과
첫 줄
A
B
C
02_csv_write.pyCSV 쓰기
CODE
import csv

with open("scores.csv", "w", encoding="utf-8", newline="") as f:
    w = csv.writer(f)
    w.writerow(["name", "score"])
    w.writerows([
        ["Alice", 92],
        ["Bob", 78],
        ["Charlie", 88],
    ])

print("저장 완료")
▶ 실행 결과
저장 완료

# scores.csv 내용:
name,score
Alice,92
Bob,78
Charlie,88
03_csv_read.pyCSV 읽기 (DictReader)
CODE
import csv

with open("scores.csv", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        name = row["name"]
        score = int(row["score"])
        print(f"{name}: {score}")
▶ 실행 결과
Alice: 92
Bob: 78
Charlie: 88
04_json.pyJSON dump / load
CODE
import json

data = {
    "name": "홍길동",
    "skills": ["Python", "SQL"],
    "active": True,
}

with open("profile.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("profile.json", encoding="utf-8") as f:
    loaded = json.load(f)

print(loaded["name"])
print(loaded["skills"])
▶ 실행 결과
홍길동
['Python', 'SQL']

📝 과제 (exercises)

직접 풀어보고, 막힐 때 정답을 펼쳐 비교해보세요.

과제 1

메모장 (텍스트 추가)

목표: 사용자 입력을 한 줄씩 notes.txt 에 추가.

요구사항
  • "a" 모드로 열기
  • quit 입력 시 종료
  • 각 줄에 시간 prefix
입출력 예시
메모: 우유 사기
메모: 책 읽기
메모: quit

# notes.txt
[14:32] 우유 사기
[14:33] 책 읽기
정답 코드 펼치기 / 접기
SOLUTION
from datetime import datetime

while True:
    text = input("메모: ")
    if text == "quit":
        break
    with open("notes.txt", "a", encoding="utf-8") as f:
        ts = datetime.now().strftime("%H:%M")
        f.write(f"[{ts}] {text}\n")
▶ 실행 결과
메모: 우유 사기
메모: 책 읽기
메모: quit

# notes.txt
[14:32] 우유 사기
[14:33] 책 읽기
과제 2

CSV 점수 통계

목표: scores.csv 를 읽어 평균/최고/최저 점수와 인원 수.

요구사항
  • csv.DictReader 사용
  • score 컬럼을 int로 변환
  • 평균 소수점 1자리
입출력 예시
인원: 3
평균: 86.0
최고: 92
최저: 78
정답 코드 펼치기 / 접기
SOLUTION
import csv

scores = []
with open("scores.csv", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        scores.append(int(row["score"]))

print(f"인원: {len(scores)}")
print(f"평균: {sum(scores)/len(scores):.1f}")
print(f"최고: {max(scores)}")
print(f"최저: {min(scores)}")
▶ 실행 결과
인원: 3
평균: 86.0
최고: 92
최저: 78
과제 3

To-Do JSON 영구 저장

목표: 할 일을 추가/조회/저장하고 재시작 시에도 유지.

요구사항
  • todos.json 에 [{ id, text, done }] 형태로 저장
  • 프로그램 시작 시 로드, 종료 시 저장
  • 명령: add/list/done <id>/quit
입출력 예시
> add 우유 사기
> list
1. [ ] 우유 사기
> done 1
> quit
저장 완료
정답 코드 펼치기 / 접기
SOLUTION
import json
from pathlib import Path

PATH = Path("todos.json")

def load():
    if PATH.exists():
        return json.loads(PATH.read_text(encoding="utf-8"))
    return []

def save(todos):
    PATH.write_text(json.dumps(todos, ensure_ascii=False, indent=2), encoding="utf-8")

todos = load()
next_id = max([t["id"] for t in todos], default=0) + 1

while True:
    cmd = input("> ").strip()
    if cmd == "quit":
        save(todos)
        print("저장 완료")
        break
    elif cmd == "list":
        for t in todos:
            mark = "x" if t["done"] else " "
            print(f"{t['id']}. [{mark}] {t['text']}")
    elif cmd.startswith("add "):
        todos.append({"id": next_id, "text": cmd[4:], "done": False})
        next_id += 1
    elif cmd.startswith("done "):
        i = int(cmd[5:])
        for t in todos:
            if t["id"] == i:
                t["done"] = True
▶ 실행 결과
> add 우유 사기
> list
1. [ ] 우유 사기
> done 1
> quit
저장 완료
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗