JSON에는 튜플 개념이 없습니다
JSON 형식에는 튜플(tuple)이라는 자료형이 존재하지 않습니다. JSON에서 지원하는 컬렉션 타입은 객체(object)와 배열(array)뿐입니다. 따라서 파이썬의 json 모듈은 튜플을 직렬화할 때 JSON에서 가장 유사한 구조인 배열(리스트)로 변환합니다.
예를 들어 다음과 같은 코드를 실행하면:
import json
data = (1, 2, 3)
print(json.dumps(data)) # 출력: [1, 2, 3]튜플 (1, 2, 3)은 JSON 문자열에서 [1, 2, 3]으로 변환됩니다.
불변성(Immutability)은 보존되지 않습니다
튜플의 핵심 특징인 불변성은 JSON 변환 과정에서 사라집니다. JSON 배열로 변환된 데이터를 다시 역직렬화하면 파이썬에서는 리스트로 복원되기 때문에, 원래 튜플이었는지 리스트였는지 구분할 수 없게 됩니다.
대안 1: pickle 사용하기
데이터의 타입 정보까지 그대로 보존하고 싶다면 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 tuple_decoder(dct):
if dct.get('__type__') == 'tuple':
return tuple(dct['items'])
return dct
data = (1, 2, 3)
encoded = json.dumps(data, cls=TupleEncoder)
decoded = json.loads(encoded, object_hook=tuple_decoder)
print(decoded) # 출력: (1, 2, 3) - 튜플로 복원됨이처럼 인코더와 디코더를 어떻게 설계하느냐에 따라 리스트와 튜플을 자유롭게 구분하여 처리할 수 있습니다.
정리
- JSON에는 튜플 개념이 없으며, 파이썬 json 모듈은 튜플을 배열로 변환합니다.
- 변환 과정에서 불변성은 보존되지 않습니다.
- 타입 보존이 필요하면 pickle을 사용할 수 있지만, 웹 전송에는 부적합합니다.
- 웹 환경에서는 커스텀 인코더·디코더를 만들어 리스트와 튜플을 구분하는 것이 가장 좋은 방법입니다.