데이터를 파일로 저장해야 하는 이유
프로그램이 종료되면 변수의 값은 사라집니다. 파일로 저장해야 다음에 다시 사용할 수 있습니다.
flowchart LR
subgraph FILE["파일 입출력"]
W["쓰기 (Write)\n데이터 → 파일"]
R["읽기 (Read)\n파일 → 데이터"]
end
MEM["메모리\n(변수)"] --> W --> DISK["디스크\n(파일)"]
DISK --> R --> MEM
파일 쓰기
# with 구문 사용 (자동으로 파일 닫힘)
with open("hello.txt", "w", encoding="utf-8") as f:
f.write("안녕하세요!\n")
f.write("파이썬 파일 쓰기 예제입니다.\n")
# 여러 줄 한 번에 쓰기
lines = ["첫 번째 줄\n", "두 번째 줄\n", "세 번째 줄\n"]
with open("lines.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
파일 모드:
| 모드 | 설명 |
|---|---|
"w" | 쓰기 (기존 내용 덮어씀) |
"a" | 추가 (기존 내용 뒤에 붙임) |
"r" | 읽기 (기본값) |
파일 읽기
# 전체 내용 읽기
with open("hello.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 한 줄씩 읽기
with open("hello.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip()으로 줄바꿈 제거
# 모든 줄을 리스트로
with open("hello.txt", "r", encoding="utf-8") as f:
lines = f.readlines() # ['첫줄\n', '둘째줄\n', ...]
파일 존재 여부 확인
import os
from pathlib import Path
# os 방식
if os.path.exists("hello.txt"):
print("파일 있음")
# pathlib 방식 (현대적)
path = Path("hello.txt")
if path.exists():
print(f"파일 크기: {path.stat().st_size} bytes")
# 디렉토리 생성
Path("output").mkdir(exist_ok=True) # 이미 있어도 에러 없음
Path("a/b/c").mkdir(parents=True, exist_ok=True) # 중간 폴더도 생성
CSV 파일 처리
import csv
# CSV 쓰기
students = [
["이름", "나이", "점수"],
["철수", 20, 85],
["영희", 22, 92],
["민준", 21, 78],
]
with open("students.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerows(students)
# CSV 읽기 (딕셔너리로)
with open("students.csv", "r", encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['이름']}: {row['점수']}점")
JSON 파일 처리
import json
# 딕셔너리를 JSON 파일로 저장
config = {
"model": "gpt-4o-mini",
"temperature": 0.7,
"max_tokens": 1000,
"system_prompt": "친절한 어시스턴트입니다."
}
with open("config.json", "w", encoding="utf-8") as f:
json.dump(config, f, ensure_ascii=False, indent=2)
저장된 파일:
{
"model": "gpt-4o-mini",
"temperature": 0.7,
"max_tokens": 1000,
"system_prompt": "친절한 어시스턴트입니다."
}
# JSON 파일 읽기
with open("config.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded["model"]) # gpt-4o-mini
print(loaded["temperature"]) # 0.7
실전: 대화 기록 저장/불러오기
LLM 챗봇의 대화 기록을 파일로 관리합니다.
import json
from datetime import datetime
from pathlib import Path
HISTORY_DIR = Path("chat_history")
HISTORY_DIR.mkdir(exist_ok=True)
def save_conversation(session_id: str, messages: list):
"""대화 기록을 JSON 파일로 저장합니다."""
data = {
"session_id": session_id,
"saved_at": datetime.now().isoformat(),
"messages": messages
}
filepath = HISTORY_DIR / f"{session_id}.json"
with open(filepath, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"저장됨: {filepath}")
def load_conversation(session_id: str) -> list:
"""저장된 대화 기록을 불러옵니다."""
filepath = HISTORY_DIR / f"{session_id}.json"
if not filepath.exists():
return [] # 기록 없으면 빈 리스트
with open(filepath, "r", encoding="utf-8") as f:
data = json.load(f)
return data["messages"]
# 사용 예시
messages = [
{"role": "user", "content": "안녕!"},
{"role": "assistant", "content": "안녕하세요!"}
]
save_conversation("user_001", messages)
loaded = load_conversation("user_001")
print(loaded[0]["content"]) # 안녕!
실전: 로그 파일 쌓기
from datetime import datetime
def write_log(message: str, level: str = "INFO"):
"""로그를 파일에 추가합니다."""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] [{level}] {message}\n"
with open("app.log", "a", encoding="utf-8") as f: # "a"는 추가 모드
f.write(log_entry)
print(log_entry.strip())
write_log("서버 시작")
write_log("사용자 로그인: 철수", "INFO")
write_log("파일을 찾을 수 없음", "ERROR")
pathlib: 경로 다루기
from pathlib import Path
# 경로 조합
base = Path(".")
data_dir = base / "data"
file_path = data_dir / "users.json"
print(file_path) # data/users.json
print(file_path.name) # users.json
print(file_path.stem) # users
print(file_path.suffix) # .json
print(file_path.parent) # data
# 특정 확장자 파일 찾기
for json_file in Path(".").glob("**/*.json"):
print(json_file)
정리
| 작업 | 코드 |
|---|---|
| 텍스트 쓰기 | open("f.txt", "w") as f: f.write(...) |
| 텍스트 읽기 | open("f.txt", "r") as f: f.read() |
| 내용 추가 | open("f.txt", "a") as f: f.write(...) |
| JSON 저장 | json.dump(data, f, ensure_ascii=False) |
| JSON 읽기 | json.load(f) |
| CSV 쓰기 | csv.writer(f).writerows(data) |
| CSV 읽기 | csv.DictReader(f) |
| 경로 처리 | Path("dir") / "file.txt" |
다음 편에서는 예외 처리 — 오류가 발생해도 프로그램이 멈추지 않게 만드는 방법을 배웁니다.