HOWTO · Python
Python 클래스 객체를 JSON으로 직렬화하는 방법
이 튜토리얼에서는 Python의 직렬화에 대해 설명하고 Python 클래스의 JSON 직렬화를 시연합니다.
이 페이지의 내용
사용자 정의 Python 인스턴스는 표준 json 인코더에 직접 전달할 수 없습니다. 먼저 JSON과 호환되는 값으로 변환한 다음, JSON 텍스트가 필요할 때 json.dumps()를 사용하세요. 그 텍스트를 대신 파일과 유사한 객체에 쓰려면 json.dump()를 사용하세요.
Python에서의 직렬화
직렬화는 데이터를 저장하거나 전송할 수 있고 나중에 다시 구성할 수 있는 표현으로 변환합니다. JSON은 객체, 배열, 문자열, 숫자, 불리언, null을 지원합니다. Python에서는 이에 대응하는 것이 딕셔너리, 리스트, 문자열, 숫자, 불리언, None입니다. 사용자 정의 클래스의 인스턴스에는 자동 JSON 표현이 없으므로, 어떤 속성을 공개할지 결정하고 그 속성들을 지원되는 값으로 변환해야 합니다.
Python 클래스를 JSON 직렬화 가능하게 만들기
JSON 인코더는 중첩된 딕셔너리와 리스트를 포함해 Python의 내장 값을 처리합니다. 사용자 정의 인스턴스의 경우, 마주치는 각 인스턴스를 딕셔너리로 변환하는 default 함수를 json.dumps()에 전달하세요. 변환이 인코더가 처리할 수 있는 값을 반환하는 한, 중첩된 사용자 정의 객체에도 이 방식이 동작합니다.
toJSON() 메서드를 사용해 JSON 클래스를 직렬화 가능하게 만들기
toJSON()은 클래스 작성자가 선택한 일반적인 메서드 이름입니다. Python의 json 모듈이 이를 자동으로 호출하지는 않습니다. 한 가지 방법은 인코더의 default 인자를 사용하고 메서드가 JSON 텍스트를 반환하게 하는 것입니다.
이 예제를 실행하세요.
import json
class Pet:
def __init__(self, name):
self.name = name
class Person:
def __init__(self, name, age, pet):
self.name = name
self.age = age
self.pet = pet
def toJSON(self):
return json.dumps(self, default=lambda value: value.__dict__, sort_keys=True)
person = Person("Kelvin", 20, Pet("Brunno"))
print(person.toJSON())
이 예제는 실행 가능한 코드로 제공되지만, 그 실행 결과는 제공되지 않았습니다. 따라서 그 출력은 여기서 검증되지 않았습니다. default 콜백은 Person과 중첩된 Pet 모두에 적용됩니다. 속성 자체가 지원되지 않는다면, 그 값에 대한 변환 규칙도 추가하세요.
JSON 직렬화를 클래스 안에 감싸기
클래스가 변환 단계를 직접 맡아 JSON과 호환되는 값들로 이루어진 딕셔너리를 반환할 수도 있습니다. 그런 다음 그 딕셔너리를 json.dumps()에 전달합니다. dataclass는 그 필드가 이미 공개할 데이터를 설명하고 있을 때 유용합니다.
from dataclasses import asdict, dataclass
import json
@dataclass
class Student:
id: int
name: str
def toJSON(self):
return asdict(self)
student = Student(id=1, name="Kelvin")
json_text = json.dumps(student.toJSON())
print(json_text)
이 예제 역시 여기서는 실행되지 않았습니다. asdict()는 dataclass 필드를 딕셔너리로 변환하고, json.dumps()는 JSON 텍스트를 반환합니다. 파일 출력의 경우, 반환된 문자열을 출력하는 대신 열린 파일과 유사한 객체로 json.dump(student.toJSON(), file_object)를 호출하세요. 두 접근법 모두 중첩된 임의의 Python 객체를 직렬화 가능하게 만들지는 않습니다. 그 값들 역시 변환되어야 합니다.