JSON to Python 변환기는 샘플 JSON을 읽어 루트용 클래스와 중첩 객체마다 하나씩 클래스를 만듭니다. 기본은 @dataclass이고 "스타일" 옵션을 Pydantic v2로 바꾸면 BaseModel 서브클래스가 나옵니다. 파일은 from __future__ import annotations로 시작하고 타입은 list[str] 같은 내장 제네릭과 str | None 같은 유니온으로 씁니다.
같은 위치에 있는 객체는 합쳐집니다. 객체 배열이면 모든 원소의 키를 합친 클래스가 만들어지고, 일부 원소에 없거나 일부에서 null인 키는 | None 타입과 None 기본값을 갖습니다. 의존하는 클래스가 먼저 나와 루트 클래스가 맨 뒤에 오고, 배열 루트는 Payload = list[PayloadItem] 같은 별칭 줄로 끝납니다. "루트 타입 이름"(기본값 Payload)이 루트 이름을 정합니다.
from_dict 같은 메서드는 만들지 않습니다. Pydantic 모델은 Payload.model_validate(data)로 파싱하고, 데이터클래스는 dacite 같은 도구로 중첩 데이터를 직접 넣어야 합니다. 입력은 브라우저 안에서 처리되며 서버로 전송되지 않습니다. 한도는 20 MiB이고 최상위 값은 객체나 배열이어야 합니다.
사용 방법
JSON 붙여넣기
샘플 데이터를 붙여넣거나 내장 샘플을 불러옵니다. 최상위 객체와 배열은 받지만 문자열, 숫자, 불리언 단일 값은 오류가 납니다.
스타일과 루트 이름 고르기
"스타일"에서 dataclass(기본값)나 Pydantic v2를 고르고,
Payload가 싫다면 "루트 타입 이름"을 바꿉니다.변환 실행
변환을 실행합니다. 문법 오류나 빈 입력은 코드 대신 오류를 보여 줍니다.
클래스 확인
다른 클래스가 참조하는 클래스가 먼저, 루트가 마지막에 나옵니다. 필드는 JSON 키 순서를 따르지만 데이터클래스에서는 기본값 없는 필드가 기본값 있는 필드보다 앞으로 옮겨집니다.
키 매핑 확인
필드 이름이 JSON 키와 다르면 데이터클래스에는
# JSON key: "..."주석이, Pydantic 모델에는Field(alias="...")가 붙습니다.복사 또는 다운로드
코드를 복사하거나
.py파일로 저장한 뒤Payload를 의미 있는 이름으로 바꿉니다.
작동 원리
JSON과 Python 타입 대응
타입은 한 위치의 모든 값으로 정합니다. 절댓값 2^63 미만인 정수 표기는 int, 소수점·지수 표기와 소수 값 및 2^63 이상의 정수는 float입니다. 따라서 19.0은 float이고 [1, 1.5]는 list[float]로 합쳐집니다. null이거나 없는 키는 필요에 따라 None 기본값이 붙은 T | None이 됩니다.
배열은 소문자 제네릭 list[T]로 씁니다. 모든 샘플에서 null인 키, 빈 배열의 원소, 서로 다른 모양이 섞인 위치는 Any가 되고 파일 맨 위에서 typing의 Any를 가져옵니다.
| JSON 값 | Python 타입 | 비고 |
|---|---|---|
| string | str | |
| true / false | bool | |
| 2^63 미만의 정수 표기 | int | Python int는 무제한이지만 값은 이미 64비트 부동소수로 읽힌 상태입니다 |
| 소수, 또는 정수와 소수가 섞인 값 | float | |
| 타입과 null이 함께 있는 값 | T | None = None | 예: str | None = None |
| 일부 객체에 없는 키 | T | None = None | 널 허용 값과 같은 타입 |
| 모든 샘플에서 null, 또는 섞인 모양 | Any | typing에서 가져옴 |
| 객체 | 클래스 | PayloadUser처럼 키 경로로 이름을 붙입니다 |
| 배열 | list[T] | 원소 클래스는 키의 단수형을 따라 PayloadItem처럼 붙습니다 |
| 빈 배열 | list[Any] | 배울 원소가 없음 |
이름 규칙
클래스 이름은 키 경로를 PascalCase로 이은 것입니다. 루트 아래 user는 PayloadUser, items 배열의 원소는 PayloadItem이 됩니다(categories는 PayloadCategory, data는 PayloadDataItem). 클래스 이름이 겹치면 2부터 숫자가 붙습니다.
필드 이름은 소문자로 바꾸고 camelCase 경계에 밑줄을 넣으며 그 밖의 문자 연속은 밑줄 하나로 합칩니다. 그래서 userName은 user_name, first name은 first_name입니다. 숫자로 시작하는 키에는 field_ 접두사가 붙어 2fa는 field_2fa가 되고, class, from, import, match, type 같은 Python 키워드에는 끝에 밑줄이 붙으며, 정리한 결과가 같아지는 키는 2, 3 접미사가 붙습니다. Pydantic 스타일에서는 model_config, copy, dict, json처럼 BaseModel 멤버와 겹치는 이름에도 끝 밑줄이 붙습니다.
userName -> user_name # JSON key: "userName"
class -> class_ # JSON key: "class"
2fa -> field_2fa # JSON key: "2fa"데이터클래스와 Pydantic
@dataclass는 __init__, __repr__, __eq__만 만들어 줍니다. 런타임에 타입을 검사하지 않고 이름이 바뀐 필드는 주석으로만 알려 주므로 데이터를 넣을 때 키는 직접 매핑해야 합니다. 데이터클래스에서는 기본값 있는 필드 뒤에 필수 필드를 둘 수 없어서 생성기가 필수 필드를 먼저 나열합니다.
Pydantic v2 스타일은 BaseModel 클래스를 쓰고 이름이 바뀐 키에는 Field(alias="userName")를 붙이므로 Payload.model_validate(data)가 원래 JSON을 받아 줍니다. Pydantic은 클래스를 만들 때 어노테이션을 평가하므로 X | None 문법에는 대체로 Python 3.10 이상이 필요하고, 데이터클래스 출력은 어노테이션을 문자열로만 저장합니다.
실제 예시
{"id":42,"user":{"name":"Ada","active":true},"roles":["admin","editor"]}from __future__ import annotations
from dataclasses import dataclass
@dataclass
class PayloadUser:
name: str
active: bool
@dataclass
class Payload:
id: int
user: PayloadUser
roles: list[str]중첩 객체마다 데이터클래스가 따로 만들어집니다. Payload가 PayloadUser를 참조하므로 PayloadUser가 먼저 나오고 루트 클래스가 마지막에 옵니다.
{"user_id":7,"userName":"Ada","first name":"Ada L","class":"admin","2fa":true,"price":19.5,"note":null,"tags":[],"mixed":[1,"a"]}from __future__ import annotations
from typing import Any
from dataclasses import dataclass
@dataclass
class Payload:
user_id: int
user_name: str # JSON key: "userName"
first_name: str # JSON key: "first name"
class_: str # JSON key: "class"
field_2fa: bool # JSON key: "2fa"
price: float
tags: list[Any]
mixed: list[Any]
note: Any = NoneuserName, first name, 2fa는 이름이 바뀌며 JSON 키가 주석으로 남습니다. class에는 밑줄이 붙고 null만 있는 키, 빈 배열, 섞인 배열은 Any가 됩니다. note는 None 기본값이 있는 선택 필드입니다.
{"items":[{"sku":"A1"},{"sku":"B2","qty":3}]}from __future__ import annotations
from dataclasses import dataclass
@dataclass
class PayloadItem:
sku: str
qty: int | None = None
@dataclass
class Payload:
items: list[PayloadItem]두 항목이 PayloadItem으로 합쳐집니다. qty는 두 번째 레코드에만 있어 int | None = None이고, 두 레코드에 모두 있는 sku는 필수로 남습니다.
{"userName":"Ada","2fa":true,"nick":null,"items":[{"sku":"A1"},{"sku":"B2","qty":3}]}from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field
class PayloadItem(BaseModel):
sku: str
qty: int | None = None
class Payload(BaseModel):
user_name: str = Field(alias="userName")
field_2fa: bool = Field(alias="2fa")
nick: Any = None
items: list[PayloadItem]스타일을 Pydantic v2로 하면 이름이 바뀐 키에 Field(alias=...)가 붙어 model_validate가 원래 JSON을 받아 주고, 선택 키에는 None 기본값이 붙습니다.
[{"id":1,"name":"Ada"},{"id":2,"email":"grace@example.com"}]from __future__ import annotations
from dataclasses import dataclass
@dataclass
class PayloadItem:
id: int
name: str | None = None
email: str | None = None
Payload = list[PayloadItem]원소들이 PayloadItem으로 합쳐지고 파일 끝에 Payload = list[PayloadItem] 줄이 붙습니다. 이 별칭은 실제 실행되는 문장이라 Python 3.9 이상이 필요합니다.
자주 하는 실수
null만 있는 키는 Any가 됩니다
붙여넣은 모든 객체에서
note가 null이면 타입을 알 수 없어None기본값이 있는Any필드가 됩니다. 값이 들어 있는 레코드를 붙여넣거나Any를 직접 바꾸세요.샘플 하나로는 키가 항상 있다고 증명할 수 없습니다
붙여넣은 모든 원소에 있는 키는 필수로 생성됩니다. API가 가끔 그 키를 생략한다면 해당 레코드에서
Payload(**data)나model_validate가 실패합니다. 선택 키가 빠진 레코드를 포함해 여러 건을 붙여넣으세요.데이터클래스는 중첩 데이터를 파싱하지 않습니다
Payload(**data)는 중첩 dict를 dict로 남기므로payload.user.name은dacite.from_dict등으로 중첩 데이터클래스를 만들기 전까지 실패합니다. Pydantic 스타일은model_validate가 중첩까지 처리합니다.이름이 바뀐 데이터클래스 필드는 직접 매핑해야 합니다
# JSON key: "userName"주석이 붙은user_name필드는 자동으로 매핑되지 않습니다. 원본 JSON을Payload(**data)로 넘기면userName이 전달되어TypeError가 납니다.Pydantic은 필드 이름이 아니라 별칭으로 채웁니다
별칭이 있는 필드는 별칭으로 채워지므로
Payload(user_name="Ada")는 모델 설정에populate_by_name=True를 넣지 않으면 거부됩니다. 원래 JSON을model_validate에 넘기세요.2^53을 넘는 정수는 이미 반올림되어 있습니다
타입 추론에서 9007199254740993을 JavaScript 숫자로 바꾸면 9007199254740992가 됩니다. Python int는 무제한이지만 이 변환에서 반올림된 자릿수는 생성 코드가 되살릴 수 없으므로 정확한 ID는 문자열로 입력하세요.
자주 묻는 질문
Pydantic 모델도 만들어 주나요?
네. "스타일"을 Pydantic v2로 바꾸면 이름이 바뀐 키에 Field(alias=...)가 붙은 BaseModel 클래스가 나옵니다. 기본값은 표준 라이브러리 데이터클래스입니다.
어느 Python 버전이 필요한가요?
데이터클래스는 3.7 이상이면 되고, 배열 루트 별칭처럼 실제로 실행되는 식의 list[str]에는 3.9가 필요합니다. 어노테이션은 from __future__ import annotations 덕분에 문자열로 저장됩니다. Pydantic 스타일은 X | None 때문에 대체로 3.10 이상이 필요합니다.
선택 필드는 어떻게 처리하나요?
배열의 일부 객체에 없거나 일부에서 null인 키는 T | None = None이 됩니다. 데이터클래스는 기본값 있는 필드 뒤에 기본값 없는 필드를 둘 수 없어서 필수 필드를 먼저 나열합니다.
필드 이름이 class_로 나오는 이유는 무엇인가요?
class가 Python 키워드라서 밑줄을 붙이고 원래 키는 주석(Pydantic은 별칭)으로 남깁니다.
JSON 배열을 붙여넣어도 되나요?
네. 원소들이 클래스 하나로 합쳐지고 마지막에 Payload = list[PayloadItem] 같은 별칭이 목록 이름을 정합니다.
from_dict 메서드도 얻을 수 있나요?
데이터클래스에서는 불가능합니다. 선언만 출력하므로 dacite.from_dict를 쓰거나 classmethod를 직접 작성하거나, Pydantic 스타일로 바꿔 model_validate를 호출하세요.
JSON이 서버로 전송되나요?
아니요. 파싱과 변환은 브라우저 안에서만 실행됩니다.
마지막 업데이트:
