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

JSON에서 Python 튜플을 보존하는 방법 완벽 가이드

JSON 형식에는 튜플(tuple)에 해당하는 자료형이 존재하지 않습니다. 그렇기 때문에 Python의 json 모듈은 튜플을 직렬화할 때 JSON에서 튜플과 가장 유사한 형태인 배열(list)로 변환합니다.

여기서 중요한 문제는 이 과정에서 튜플의 핵심 특성인 불변성(immutability)이 사라진다는 점입니다. 역직렬화된 결과는 일반 리스트로 복원되며, 원래 튜플이었는지 여부를 알 수 없게 됩니다.

튜플을 보존하는 두 가지 방법

1. Pickle 사용하기

Python의 pickle 모듈을 사용하면 튜플의 자료형과 불변성을 그대로 유지할 수 있습니다. 다만 pickle은 데이터를 .pkl 파일로 저장하기 때문에 JSON 파일에는 저장할 수 없습니다. 따라서 웹을 통해 데이터를 주고받는 상황에서는 적합하지 않습니다. 또한 pickle은 역직렬화 시 임의 코드 실행 위험이 있으므로, 반드시 신뢰할 수 있는 소스의 데이터에만 사용해야 합니다.

2. 커스텀 인코더/디코더 작성하기

웹 환경에서 가장 권장되는 방법은 자신만의 인코더와 디코더를 작성하여 리스트와 튜플을 구분하는 것입니다. 예를 들어 튜플을 특별한 마커가 포함된 JSON 객체로 변환하면 됩니다.

import json

class TupleEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, tuple):
            return {'__type__': 'tuple', 'items': list(obj)}
        return super().default(obj)

def as_tuple(dct):
    if dct.get('__type__') == 'tuple':
        return tuple(dct['items'])
    return dct

data = {'point': (1, 2), 'values': [3, 4]}
encoded = json.dumps(data, cls=TupleEncoder)
decoded = json.loads(encoded, object_hook=as_tuple)

print(decoded['point'])       # (1, 2) — 튜플로 복원됨
print(type(decoded['point'])) # <class 'tuple'>

이 방식은 인코더와 디코더를 어떻게 설계하느냐에 따라 리스트와 튜플을 자유롭게 구분할 수 있으며, JSON 형식을 유지한 채 웹 전송에도 문제없이 사용할 수 있다는 큰 장점이 있습니다.

정리

  • JSON에는 튜플 개념이 없기 때문에 Python 튜플은 자동으로 배열로 변환되며 불변성은 유지되지 않습니다.
  • 불변성을 유지하려면 pickle(로컬 파일 저장용) 또는 커스텀 인코더/디코더(웹 전송용)를 활용하세요.
  • 웹 환경에서 데이터를 주고받아야 한다면 커스텀 인코더/디코더가 가장 실용적인 선택입니다.