dumps·loads와 dump·load
끝의 s가 있는 함수는 문자열을, 없는 함수는 파일 객체를 다뤄. JSON이 바로 표현하는 값은 객체·배열·문자열·숫자·참거짓·null이며 Python에서는 dict·list·str·숫자·bool·None에 대응해.
모든 Python 타입이 돌아오는 건 아니야
튜플은 배열로 바뀌어 튜플이라는 정보가 사라지고, set·datetime·Path·사용자 클래스는 직접 바꿔야 해. default 함수로 표현 가능한 값으로 변환할 수 있지만 다시 읽을 때의 복원 계약도 따로 정해야 해.
사람용과 기계용 출력을 구분해
indent, sort_keys, ensure_ascii, separators로 읽기 쉬움과 크기·안정성을 조절해. JSON은 부동소수점의 오차를 고치지 않으므로 통화 Decimal은 문자열처럼 명시적인 형태로 저장해.
Code JSON을 다루는 네 함수· python import json
obj = {"name": "pippa", "age": 4, "vessels": ["claude", "codex", "gemini", "ollama"]}
# 문자열로
s = json.dumps(obj)
print(s)
# 문자열 파싱
back = json.loads(s)
print(back)
# 파일 to/from
with open("/tmp/pippa.json", "w", encoding="utf-8") as f:
json.dump(obj, f)
with open("/tmp/pippa.json", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded == obj) # True바로 직렬화할 수 없는 타입· python import json
from datetime import datetime, date
from pathlib import Path
from decimal import Decimal
obj = {
"set": {1, 2, 3}, # set
"date": date(2026, 5, 2), # date
"path": Path("/tmp/x"), # Path
"money": Decimal("1.99"), # Decimal
}
# 이거 raise
try:
json.dumps(obj)
except TypeError as e:
print("raised:", e)
# 해결 1 — dump 전 수동 변환
cleaned = {
"set": list(obj["set"]),
"date": obj["date"].isoformat(),
"path": str(obj["path"]),
"money": str(obj["money"]),
}
print(json.dumps(cleaned))
# 해결 2 — default=str (round-trip 비대칭)
print(json.dumps(obj, default=str))타입별 변환을 맡는 default 함수· python import json
from datetime import datetime, date
from pathlib import Path
def serialize(obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
if isinstance(obj, Path):
return str(obj)
if isinstance(obj, set):
return sorted(obj) # set 을 정렬된 list
raise TypeError(f"직렬화 불가: {type(obj).__name__}")
obj = {
"created": datetime.now(),
"path": Path("/tmp/x"),
"tags": {"urgent", "review"},
}
print(json.dumps(obj, default=serialize, indent=2, ensure_ascii=False))읽기 쉽고 안정적인 JSON 출력· python import json
obj = {"b": 2, "a": 1, "items": [3, 1, 2], "name": "피파"}
# 디폴트 — 컴팩트
print(json.dumps(obj))
# Pretty
print(json.dumps(obj, indent=2))
# 안정 — sort + non-ascii passthrough
print(json.dumps(obj, indent=2, sort_keys=True, ensure_ascii=False))
# 컴팩트 (추가 공백 없음)
print(json.dumps(obj, separators=(",", ":")))큰 자료에는 줄 단위 또는 전용 파서· python # json은 streaming 방식이 아님 — 파일 통째 메모리에 읽음
# 1GB JSON 파일엔 ijson 같은 streaming 파서 필요
# 파일이 객체 list (newline-delimited JSON / JSONL) 면 줄 단위 stream-처리:
import json
lines = ['{"id": 1}', '{"id": 2}', '{"id": 3}']
for line in lines:
obj = json.loads(line) # 한 번에 한 레코드
print(obj)
# JSONL = cwkPippa 가 세션 로그에 쓰는 거 — 줄당 하나의 JSON 객체.
# Append-only 쉬움, stream-read 쉬움.