JSON 개념 정리와 자주 일어나는 JSONDecodeError에 대해

하나둘셋·2024년 12월 17일

OpenAI의 구조화된 출력(Structured Outputs)와 웹 통신으로 JSON 데이터를 다루면서 JSON에 대해 공부하게 되었다. 이번 게시물에서는 JSON의 개념 정리를 짧게 해보고 자주 일어나는 오류에 대해 살펴 보자 😶


JSON 개념 정리

JSON은?

  • 데이터를 교환하기 위해 경량화된 형식
  • 인간이 읽고 쓰기에 용이하고 기계가 파싱하고 생성하기도 간편한 형식
  • 웹 어플리케이션 데이터 교환에 많이 사용

기본 JSON 문법

{
	"first_name" : "Katie",
	"last_name" : "Rodgers"
}
  • 키-값의 쌍으로 데이터가 쓰인다.
  • 여러 쌍의 키-값의 모음은 객체라고 한다. 객체는 중괄호 안에 있다.

직렬화(serialization)

import json

data = {"response" : "hi", "info": None}

json_object = json.dumps(data)

print(type(json_object))
print(json_object)

# 출력
# <class 'str'>
# {"response": "hi", "info": null}

파이썬에서json.dumps() 함수를 이용해 파이썬 객체를 JSON 형식의 문자열로 변환할 수 있고 이를 직렬화(serialization)라고 한다. 변환된 데이터는 파일에 저장하거나 네트워크를 통해 전송할 수 있다.

파이썬의 None 값은 JSON으로 변환되면 null로 바뀌고 JSON 모듈은 항상 바이트 객체가 아닌 문자열 객체를 생성한다는 것을 참고하길 바란다.

json.dump() 함수는 파이썬 객체를 JSON 형식 스트림(파일류 객체)로 직렬화 한다는 점에서 차이가 있다.


역직렬화(deserialization)

import json

string = '{"response" : "hi", "info": null}'

json_object = json.loads(string)

print(type(json_object))
print(json_object)

#출력
#<class 'dict'>
#{'response': 'hi', 'info': None}

json.loads() 함수를 통해 JSON 형식의 문자열이나 바이트 배열 객체를 파이썬 객체로 변환할 수 있다. 이를 역직렬화(deserialization)라고 한다.

위의 경우는 JSON 형식의 문자열이 파이썬 객체인 딕셔너리로 변환된 모습이다. 역직렬화 되는 데이터가 유효한 JSON 문자열이 아닌 경우 JSONDecodeError를 발생시키는 데 몇가지 오류는 아래에서 살펴 본다.

json.load()는 JSON 형식을 포함하는 텍스트나 바이너리 파일을 파이썬 객체로 역직렬화 하는 함수이다.



JSONDecodeError: 변환할 때 조심해야 하는 것

1. JSON의 키-값은 모두 이중 따옴표(”)로 둘러 쌓여 있어야 함

import json

# 옳게된 경우: '{"response" : "hi", "info": null}'
string = "{'response' : 'hi', 'info': null}"

# json.loads() 부분 오류 발생!!
json_object = json.loads(string)
  • 발생한 오류: json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

2. JSON 값 안에서 이중 따옴표를 사용할 수 없음 - 그냥 따옴표는 사용 가능

import json

# 옳게된 경우: '{"response" : "안녕 너 \'김치\' 먹어 봤어? ", "info": null}'
string = '{"response" : "안녕 너 "김치" 먹어 봤어? ", "info": null}'

# json.loads() 부분 오류 발생!!
json_object = json.loads(string)
  • 발생한 오류: json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 22 (char 21)

3. JSON 값 내에 제어 문자 포함될 수 없음

import json

string = '{"response" : "안녕 너 \'김치\' 먹어 봤어? \n", "info": null}'

# json.loads() 부분 오류 발생!!
json_object = json.loads(string)
print(json_object)

0-31 범위의 문자 코드인 \t \n \0 \r 같은 제어 문자가 문자열 내부에 허용될 수 없다.

  • 발생한 오류: json.decoder.JSONDecodeError: Invalid control character at: line 1 column 33 (char 32)
  • 해결 방법
    json.loads() 함수에 strict 파라미터를 False로 설정하면 JSON 문자열 내에 제어 문자가 허용된다.
    json_object = json.loads(string, strict=False)
    print(json_object)
    
    # 출력
    # {'response': "안녕 너 '김치' 먹어 봤어? \n", 'info': None}

파이썬 공식 문서

profile
하나씩 뚝딱뚝딱

0개의 댓글