Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python JSON 인코더·디코더 완벽 가이드 – json 모듈 핵심 정리

JSON(JavaScript Object Notation)은 경량 데이터 교환 형식으로, Python의 pickle과 비슷한 역할을 합니다. 다만 pickle 직렬화는 Python에 종속적인 반면, JSON은 대부분의 프로그래밍 언어에서 지원된다는 점이 큰 차이입니다. Python 표준 라이브러리의 json 모듈은 pickle 및 marshal 모듈과 유사한 객체 직렬화 기능을 제공합니다.

pickle 모듈과 마찬가지로 json 모듈도 Python 객체를 JSON 인코딩 문자열로 직렬화하는 dumps()loads() 함수를 제공하며, dump()load() 함수는 파일에 직렬화된 객체를 쓰거나 읽는 데 사용됩니다.

dumps()

이 함수는 Python 객체를 JSON 형식의 문자열로 변환합니다.

loads()

이 함수는 JSON 문자열을 다시 Python 객체로 변환(역직렬화)합니다.

다음 예제는 두 함수의 기본적인 사용법을 보여줍니다.

>>> import json
>>> data = ['Rakesh', {'marks': (50, 60, 70)}]
>>> s = json.dumps(data)
>>> s
'["Rakesh", {"marks": [50, 60, 70]}]'
>>> json.loads(s)
['Rakesh', {'marks': [50, 60, 70]}]

주요 옵션: sort_keys와 indent

dumps() 함수는 선택적 sort_keys 인자를 받습니다. 기본값은 False이며, True로 설정하면 딕셔너리의 키가 정렬된 순서로 JSON 문자열에 출력됩니다.

>>> data = {"marks": 50, "age": 20, "rank": 5}
>>> s = json.dumps(data, sort_keys=True)
>>> s
'{"age": 20, "marks": 50, "rank": 5}'
>>> json.loads(s)
{'age': 20, 'marks': 50, 'rank': 5}

또한 indent 매개변수에 숫자를 지정하면 pprint 출력과 유사하게 들여쓰기가 적용된 보기 좋은 형태의 JSON 문자열을 얻을 수 있습니다.

>>> data = ['Rakesh', {'marks': (50, 60, 70)}]
>>> s = json.dumps(data, indent=2)
>>> print(s)
[
  "Rakesh",
  {
    "marks": [
      50,
      60,
      70
    ]
  }
]

객체 지향 API: JSONEncoder와 JSONDecoder

json 모듈에는 위 함수들에 대응하는 객체 지향 API도 포함되어 있으며, 모듈 안에 JSONEncoderJSONDecoder 두 클래스가 정의되어 있습니다.

JSONEncoder 클래스

이 클래스의 객체는 Python 데이터 구조를 JSON으로 인코딩합니다. 각 Python 데이터 타입은 아래 표와 같이 대응되는 JSON 타입으로 변환됩니다.

PythonJSON
dictobject
list, tuplearray
strstring
int, float, int·float 기반 Enumnumber
Truetrue
Falsefalse
Nonenull

JSONEncoder 클래스는 JSONEncoder() 생성자로 인스턴스화하며, 주요 메서드와 속성은 다음과 같습니다.

  • encode() − Python 객체를 JSON 형식으로 직렬화합니다.

  • iterencode() − 객체를 인코딩하고, 각 항목의 인코딩된 조각을 하나씩 생성(yield)하는 이터레이터를 반환합니다.

  • indent − 인코딩된 문자열의 들여쓰기 수준을 결정합니다.

  • sort_keys − true/false 값으로 키를 정렬된 순서로 출력할지 지정합니다.

  • check_circular − true이면 컨테이너 타입 객체의 순환 참조(circular reference) 여부를 검사합니다.

다음 예제는 Python 리스트 객체를 인코딩합니다.

>>> e = json.JSONEncoder()
>>> e.encode(data)
'["Rakesh", {"marks": [50, 60, 70]}]'

iterencode() 메서드를 사용하면 인코딩 결과가 조각 단위로 출력됩니다.

>>> for obj in e.iterencode(data):
...     print(obj)
[
"Rakesh"
{
"marks"
:
[
50
, 60
, 70
]
}
]

JSONDecoder 클래스

이 클래스의 객체는 JSON 문자열을 다시 Python 데이터 구조로 디코딩하는 데 사용되며, 핵심 메서드는 decode()입니다. 다음 예제는 앞서 인코딩한 문자열에서 원래의 Python 리스트 객체를 복원합니다.

>>> d = json.JSONDecoder()
>>> d.decode(s)
['Rakesh', {'marks': [50, 60, 70]}]

파일·스트림과 함께 사용하기

json 모듈은 JSON 데이터를 파일류(file-like) 객체, 즉 디스크 파일이나 바이트 스트림에 쓰고 다시 읽어오기 위한 dump()load() 함수를 제공합니다.

dump()

이 함수는 Python 객체를 JSON 형식으로 인코딩해 파일에 기록합니다. 파일은 쓰기 권한으로 열려 있어야 합니다.

>>> data = ['Rakesh', {'marks': (50, 60, 70)}]
>>> fp = open('json.txt', 'w')
>>> json.dump(data, fp)
>>> fp.close()

이 코드는 현재 디렉터리에 'json.txt' 파일을 생성하며, 파일 내용은 다음과 같습니다.

["Rakesh", {"marks": [50, 60, 70]}]

load()

이 함수는 파일에서 JSON 데이터를 읽어 Python 객체를 구성합니다. 파일은 읽기 권한으로 열려 있어야 합니다.

>>> fp = open('json.txt', 'r')
>>> ret = json.load(fp)
>>> ret
['Rakesh', {'marks': [50, 60, 70]}]
>>> fp.close()

정리하면, 문자열 변환에는 dumps()/loads(), 파일 입출력에는 dump()/load()를 사용하고, 더 세밀한 제어가 필요할 때는 JSONEncoderJSONDecoder 클래스를 활용하면 됩니다.