Python과 JSON: 완벽한 가이드 2026
Python에서 JSON을 마스터하세요. json 모듈, 파싱, 직렬화, 파일 작업 및 고급 기술에 대한 종합 가이드입니다.
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# Python과 JSON: 완벽한 가이드 2026
Python은 강력한 json 모듈로 JSON 작업을 위한 훌륭한 지원을 제공합니다. 이 종합 가이드는 Python에서 JSON을 다루는 모든 것을 다룹니다.
json 모듈
Python의 표준 라이브러리에는 내장 json 모듈이 포함되어 있습니다:
import json
주요 메서드
- json.dumps(): Python 객체 → JSON 문자열
- json.loads(): JSON 문자열 → Python 객체
- json.dump(): Python 객체 → JSON 파일
- json.load(): JSON 파일 → Python 객체
JSON 파싱 (loads)
기본 사용
import json
# JSON 문자열
json_string = '{"name": "홍길동", "age": 30, "city": "서울"}'
# Python 딕셔너리로 파싱
user = json.loads(json_string)
print(user['name']) # 출력: 홍길동
print(user['age']) # 출력: 30
print(type(user)) # 출력: <class 'dict'>
배열 파싱
json_array = '[{"id": 1, "name": "김철수"}, {"id": 2, "name": "이영희"}]'
users = json.loads(json_array)
for user in users:
print(f"ID: {user['id']}, 이름: {user['name']}")
중첩된 구조
json_data = '''
{
"company": "테크 이노베이션",
"address": {
"street": "테헤란로 123",
"city": "서울",
"country": "한국"
},
"employees": [
{"name": "김철수", "role": "개발자"},
{"name": "이영희", "role": "디자이너"}
]
}
'''
company = json.loads(json_data)
print(company['address']['city']) # 서울
print(company['employees'][0]['name']) # 김철수
JSON 직렬화 (dumps)
기본 사용
import json
user = {
"name": "홍길동",
"age": 30,
"city": "서울",
"skills": ["Python", "JavaScript", "Go"]
}
# JSON 문자열로 변환
json_string = json.dumps(user, ensure_ascii=False)
print(json_string)
예쁘게 출력
# 들여쓰기 2칸
formatted = json.dumps(user, indent=2, ensure_ascii=False)
print(formatted)
결과:
{
"name": "홍길동",
"age": 30,
"city": "서울",
"skills": [
"Python",
"JavaScript",
"Go"
]
}
키 정렬
data = {
"zebra": 1,
"apple": 2,
"mango": 3
}
# 키를 알파벳순으로 정렬
sorted_json = json.dumps(data, indent=2, sort_keys=True)
print(sorted_json)
결과:
{
"apple": 2,
"mango": 3,
"zebra": 1
}
파일 작업
JSON 파일 읽기
import json
# JSON 파일 읽기
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
print(data)
JSON 파일 쓰기
import json
user = {
"name": "홍길동",
"age": 30,
"skills": ["Python", "Django"]
}
# JSON 파일로 저장
with open('user.json', 'w', encoding='utf-8') as f:
json.dump(user, f, indent=2, ensure_ascii=False)
안전한 파일 읽기
import json
from pathlib import Path
def read_json_file(filepath, default=None):
"""JSON 파일을 안전하게 읽기"""
try:
with open(filepath, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f"파일을 찾을 수 없음: {filepath}")
return default
except json.JSONDecodeError as e:
print(f"JSON 파싱 오류: {e}")
return default
except Exception as e:
print(f"오류: {e}")
return default
# 사용
data = read_json_file('config.json', {})
데이터 타입 매핑
Python → JSON
| Python | JSON |
|--------|------|
| dict | object |
| list, tuple | array |
| str | string |
| int, float | number |
| True | true |
| False | false |
| None | null |
python_data = {
"string": "텍스트",
"number": 42,
"float": 3.14,
"boolean": True,
"none": None,
"list": [1, 2, 3],
"tuple": (4, 5, 6), # JSON에서는 array가 됨
"dict": {"key": "value"}
}
json_string = json.dumps(python_data, indent=2)
print(json_string)
API 요청
requests 라이브러리 사용
import requests
import json
# GET 요청
response = requests.get('https://api.example.com/users')
users = response.json() # 자동으로 JSON 파싱
for user in users:
print(user['name'])
POST 요청
import requests
new_user = {
"name": "홍길동",
"email": "hong@example.com",
"age": 30
}
response = requests.post(
'https://api.example.com/users',
json=new_user # 자동으로 JSON으로 변환
)
if response.status_code == 201:
created_user = response.json()
print(f"사용자 생성됨: {created_user['id']}")
오류 처리
import requests
import json
def fetch_data(url):
"""API에서 JSON 데이터 가져오기"""
try:
response = requests.get(url, timeout=5)
response.raise_for_status() # HTTP 오류 확인
return response.json()
except requests.exceptions.Timeout:
print("요청 시간 초과")
except requests.exceptions.HTTPError as e:
print(f"HTTP 오류: {e}")
except requests.exceptions.JSONDecodeError:
print("유효하지 않은 JSON 응답")
except Exception as e:
print(f"오류: {e}")
return None
# 사용
data = fetch_data('https://api.example.com/data')
사용자 정의 인코더/디코더
날짜/시간 처리
import json
from datetime import datetime
# 사용자 정의 인코더
class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
# 사용
data = {
"event": "회의",
"timestamp": datetime.now()
}
json_string = json.dumps(data, cls=DateTimeEncoder, indent=2)
print(json_string)
사용자 정의 디코더
import json
from datetime import datetime
def datetime_decoder(dct):
"""날짜 문자열을 datetime 객체로 변환"""
for key, value in dct.items():
if isinstance(value, str):
try:
dct[key] = datetime.fromisoformat(value)
except (ValueError, AttributeError):
pass
return dct
# 사용
json_string = '{"event": "회의", "timestamp": "2026-01-16T10:30:00"}'
data = json.loads(json_string, object_hook=datetime_decoder)
print(type(data['timestamp'])) # <class 'datetime.datetime'>
클래스 직렬화
import json
class User:
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = email
def to_dict(self):
"""객체를 딕셔너리로 변환"""
return {
"name": self.name,
"age": self.age,
"email": self.email
}
@classmethod
def from_dict(cls, data):
"""딕셔너리에서 객체 생성"""
return cls(data['name'], data['age'], data['email'])
# 직렬화
user = User("홍길동", 30, "hong@example.com")
json_string = json.dumps(user.to_dict(), indent=2, ensure_ascii=False)
# 역직렬화
data = json.loads(json_string)
user_restored = User.from_dict(data)
Pydantic로 검증
from pydantic import BaseModel, EmailStr, validator
from typing import List
class User(BaseModel):
name: str
age: int
email: EmailStr
skills: List[str]
@validator('age')
def age_must_be_positive(cls, v):
if v < 0:
raise ValueError('나이는 양수여야 합니다')
return v
# JSON에서 유효성 검증된 객체 생성
json_data = '''
{
"name": "홍길동",
"age": 30,
"email": "hong@example.com",
"skills": ["Python", "Django"]
}
'''
user = User.parse_raw(json_data)
print(user.name) # 홍길동
# 객체를 JSON으로
json_string = user.json(indent=2, ensure_ascii=False)
print(json_string)
대용량 JSON 파일
스트리밍 읽기
import json
def stream_json_array(filepath):
"""대용량 JSON 배열 스트리밍"""
with open(filepath, 'r', encoding='utf-8') as f:
# 첫 번째 '[' 건너뛰기
f.read(1)
for line in f:
line = line.strip()
if line and line != ']':
# 후행 쉼표 제거
if line.endswith(','):
line = line[:-1]
try:
obj = json.loads(line)
yield obj
except json.JSONDecodeError:
continue
# 사용
for item in stream_json_array('large_data.json'):
process(item)
ijson 라이브러리 사용
import ijson
def process_large_json(filepath):
"""ijson으로 대용량 JSON 처리"""
with open(filepath, 'rb') as f:
# 배열의 각 항목 반복
for item in ijson.items(f, 'item'):
process(item)
# 설치: pip install ijson
모범 사례
1. 항상 ensure_ascii=False 사용
# 좋음 - 한글이 올바르게 표시됨
json.dumps(data, ensure_ascii=False)
# 나쁨 - 한글이 유니코드 이스케이프로 표시됨
json.dumps(data) # {"name": "\ud64d\uae38\ub3d9"}
2. 인코딩 명시
# 좋음
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
# 나쁨 - 플랫폼 기본 인코딩 사용
with open('data.json', 'r') as f:
data = json.load(f)
3. 예외 처리
import json
def safe_loads(json_string, default=None):
"""안전한 JSON 파싱"""
try:
return json.loads(json_string)
except json.JSONDecodeError as e:
print(f"JSON 파싱 오류: {e}")
return default
# 사용
data = safe_loads('유효하지 않은 JSON', {})
4. 타입 힌트 사용
from typing import Dict, List, Any, Optional
import json
def load_config(filepath: str) -> Optional[Dict[str, Any]]:
"""설정 파일 로드"""
try:
with open(filepath, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
print(f"오류: {e}")
return None
def save_config(filepath: str, config: Dict[str, Any]) -> bool:
"""설정 파일 저장"""
try:
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
return True
except Exception as e:
print(f"오류: {e}")
return False
성능 최적화
ujson 사용
import ujson
# ujson은 표준 json보다 빠름
data = ujson.loads(json_string)
json_string = ujson.dumps(data)
# 설치: pip install ujson
orjson 사용
import orjson
# 가장 빠른 JSON 라이브러리
data = orjson.loads(json_bytes)
json_bytes = orjson.dumps(data)
# 설치: pip install orjson
벤치마크
| 라이브러리 | 파싱 (ms) | 직렬화 (ms) |
|-----------|-----------|-------------|
| json | 100 | 80 |
| ujson | 40 | 35 |
| orjson | 25 | 20 |
실용적인 예제
구성 관리자
import json
from pathlib import Path
from typing import Dict, Any
class ConfigManager:
def __init__(self, config_file: str):
self.config_file = Path(config_file)
self.config: Dict[str, Any] = {}
self.load()
def load(self):
"""구성 로드"""
if self.config_file.exists():
with open(self.config_file, 'r', encoding='utf-8') as f:
self.config = json.load(f)
def save(self):
"""구성 저장"""
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(self.config, f, indent=2, ensure_ascii=False)
def get(self, key: str, default=None):
"""값 가져오기"""
return self.config.get(key, default)
def set(self, key: str, value: Any):
"""값 설정"""
self.config[key] = value
self.save()
# 사용
config = ConfigManager('app_config.json')
config.set('theme', 'dark')
theme = config.get('theme', 'light')
데이터 변환
import json
import csv
def json_to_csv(json_file, csv_file):
"""JSON 배열을 CSV로 변환"""
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
if not data:
return
keys = data[0].keys()
with open(csv_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(data)
# 사용
json_to_csv('users.json', 'users.csv')
결론
Python은 json 모듈을 통해 훌륭한 JSON 지원을 제공합니다. 파싱, 직렬화, 파일 작업 및 고급 기술을 마스터하면 Python 애플리케이션에서 JSON을 효과적으로 작업할 수 있습니다.
주요 요점:- ✓ json.loads()/dumps() 사용
- ✓ ensure_ascii=False로 한글 처리
- ✓ 항상 예외 처리
- ✓ Pydantic으로 검증
- ✓ 대용량 데이터는 스트리밍
- ✓ 성능이 중요하면 ujson/orjson
행복한 Python JSON 코딩하세요!
관련 글
JSON이란 무엇인가? JavaScript Object Notation 완벽 가이드
JSON(JavaScript Object Notation)의 기본 개념부터 실제 활용까지. 웹 개발의 필수 데이터 형식인 JSON을 완벽하게 이해해보세요.
JavaScript와 JSON: 완벽한 가이드 2026
JavaScript에서 JSON을 마스터하세요. JSON.parse(), JSON.stringify(), 오류 처리, fetch API 및 모범 사례에 대한 완벽한 가이드입니다.
JSON API와 REST 서비스: 현대 웹 개발의 핵심
JSON API와 REST 서비스의 모든 것을 배워보세요. RESTful 설계 원칙, 실용적인 예제, 모범 사례까지 완벽 정리.