파이썬 JSON: 인코딩, 디코딩, 파일 처리 실전 가이드
파이썬 JSON: 인코딩, 디코딩, 파일 처리 실전 가이드
파이썬에서 JSON이란?
JSON(JavaScript Object Notation)은 가장 널리 쓰이는 텍스트 기반 데이터 교환 포맷입니다. 파이썬에서 네이티브 데이터 구조로 직접 매핑: 객체는 dict, 배열은 list, 문자열/숫자/불리언/null은 각각 str, int/float, bool, None으로 변환. 표준 라이브러리 json 모듈이 모든 변환 처리.
파이썬 JSON 라이브러리
스크립트에서 한 번 임포트:
import json
모듈은 네 가지 핵심 메서드 제공:
| 메서드 | 설명 |
| dumps() | 파이썬 객체를 JSON 문자열로 변환. |
| dump() | JSON 문자열을 파일 객체에 직접 쓰기. |
| loads() | JSON 문자열을 파이썬 객체로 파싱. |
| load() | JSON 파일을 읽어 파이썬 객체로 파싱. |
파이썬 → JSON (인코딩)
인코딩은 파이썬 데이터 타입을 JSON으로 변환하는 과정. 기본 매핑:
| 파이썬 | JSON |
| dict | Object |
| list | Array |
| str/unicode | String |
| int/long | Number (int) |
| float | Number (real) |
| True | true |
| False | false |
| None | null |
json.dumps() 예제:
import json
x = {
"name": "Ken",
"age": 45,
"married": True,
"children": ("Alice", "Bob"),
"pets": ["Dog"],
"cars": [
{"model": "Audi A1", "mpg": 15.1},
{"model": "Zeep Compass", "mpg": 18.1}
]
}
# 키 정렬해 예쁘게 출력
sorted_string = json.dumps(x, indent=4, sort_keys=True)
print(sorted_string)
출력: 정렬된 키와 들여쓰기로 포맷된 JSON.
파일에 JSON 객체 쓰기는 json.dump()로 간단:
with open('json_file.json', 'w') as file_write:
json.dump(x, file_write, indent=4, sort_keys=True)
스크립트 실행 후 json_file.json에 직렬화된 데이터 저장.
JSON → 파이썬 (디코딩)
디코딩은 역매핑으로 JSON 문자열/파일을 네이티브 파이썬 객체로 복원. 변환 표는 인코딩 표와 미러링:
| JSON | 파이썬 |
| Object | dict |
| Array | list |
| String | str |
| Number (int) | int |
| Number (real) | float |
| true | True |
| false | False |
| null | None |
json.loads() 예제:
import json
person_data = '{"person": {"name": "Kenn", "sex": "male", "age": 28}}'
obj = json.loads(person_data)
print(obj)
print(type(obj))
print(obj.get('person'))
출력: {'person': {'name': 'Kenn', 'sex': 'male', 'age': 28}} / <class 'dict'> / {'name': 'Kenn', 'sex': 'male', 'age': 28}
JSON 파일 직접 읽기:
with open('json_file.json') as f:
data = json.load(f)
print(data)
압축 및 예쁘게 출력 인코딩
네트워크 전송용 압축 인코딩은 공백 제거:
lst = ['a', 'b', 'c', {"4": 5, "6": 7}]
compact = json.dumps(lst, separators=(',', ':'))
print(compact) # ["a","b","c",{"4":5,"6":7}]
사람 읽기 좋게 예쁘게 출력하려면 들여쓰기 사용:
dic = {"a": 4, "b": 5}
pretty = json.dumps(dic, indent=4, separators=(',', ': '))
print(pretty)
출력: 들여쓰기 된 JSON.
복잡한 객체 인코딩
json 모듈은 임의 객체 직렬화 못 함. complex 숫자 처리 위해 default 함수 제공:
def complex_encode(o):
if isinstance(o, complex):
return [o.real, o.imag]
raise TypeError(f"{repr(o)} is not JSON serializable")
print(json.dumps(4 + 5j, default=complex_encode)) # [4.0, 5.0]
복잡한 객체 디코딩
object_hook로 커스텀 마커 감지해 복소수 재구성:
def is_complex(obj):
if "__complex__" in obj:
return complex(obj["real"], obj["img"])
return obj
complex_obj = json.loads('{"__complex__": true, "real": 4, "img": 5}', object_hook=is_complex)
print(complex_obj) # (4+5j)
직렬화/역직렬화 클래스
JSONEncoder와 JSONDecoder 클래스로 세밀한 제어:
JSONEncoder.default(o) – 커스텀 객체 직렬화 오버라이드.
JSONEncoder.encode(o) – JSON 문자열 반환.
JSONEncoder.iterencode(o) – 출력 문자열 반복.
JSONDecoder.decode(s) – JSON 문자열 파싱.
JSONDecoder.raw_decode(s) – 주어진 인덱스부터 파싱.
예제:
from json.encoder import JSONEncoder
print(JSONEncoder().encode({"colour": ["red", "yellow", "green"]}))
URL에서 JSON 가져오기
requests로 실시간 JSON 피드 다운로드 (예: CityBike NYC):
import json, requests
response = requests.get("https://feeds.citibikenyc.com/stations/stations.json")
bike_dict = json.loads(response.text)
print(bike_dict['stationBeanList'][0])
JSON 예외 처리
주 예외는 json.JSONDecodeError (ValueError 서브클래스). 처리 예:
try:
with open('bad.json') as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"잘못된 JSON: {e}")
특수 숫자 값
RFC 8259는 Infinity, NaN 불허하지만 파이썬 인코더는 문자열로 표현:
print(json.dumps(float('inf'))) # Infinity
print(json.dumps(float('nan'))) # NaN
JSON 중복 키
키가 여러 번 나타나면 json.loads()는 마지막 발생만 유지:
json.loads('{"a": 1, "a": 2, "a": 3}') # -> {'a': 3}
명령줄 도구
json.tool 모듈로 명령줄에서 JSON 포맷/검증:
$ echo '{"name": "Kings Arthur"}' | python3 -m json.tool
{ "name": "Kings Arthur" }
파이썬 JSON 장점
json 모듈로 네이티브 지원.
- 예쁘게 출력으로 사람이 읽기 쉬움.
- API, 설정, 데이터 저장에 널리 채택.
- 언어 중립적, 경량.
한계
- 커스텀 인코더 없인 사용자 정의 데이터 타입 미지원.
- 최대 재귀 깊이 제한으로 깊게 중첩된 구조 제한.
- 큰 문서 전체 로드 시 메모리 집약적.
파이썬 JSON 치트 시트
| 함수 | 설명 |
| json.dumps(obj) | 파이썬 객체 JSON 문자열로 직렬화. |
| json.dump(obj, file) | JSON 문자열 파일에 쓰기. |
| json.dumps(obj, separators=(",", ":")) | 공백 없는 압축 표현. |
| json.dumps(obj, indent=4) | 들여쓰기로 예쁘게 출력. |
| json.dumps(obj, sort_keys=True) | 딕셔너리 키 알파벳순 정렬. |
| json.dumps(obj, default=custom) | 미지원 객체 인코딩. |
| JSONEncoder().encode(obj) | 인코더 클래스로 수동 직렬화. |
| json.loads(s) | JSON 문자열 파이썬 객체로 파싱. |
| json.loads(s, object_hook=custom) | 커스텀 역직렬화 로직. |
| JSONDecoder().decode(s) | 디코더 클래스로 수동 역직렬화. |