JSON sang Python

Tạo Python dataclasses từ JSON

Thử ví dụ
Tên class gốc:

Đầu vào JSON

Đầu ra Python

Chạy cục bộ · An toàn để dán thông tin bí mật
Python dataclasses sẽ hiển thị ở đây…

Chuyển đổi JSON sang Python Dataclass là gì?

Chuyển đổi JSON sang Python dataclass lấy một đối tượng JSON thô và tạo ra tập hợp các định nghĩa Python dataclass với type annotations chính xác. Module dataclasses của Python, được giới thiệu trong PEP 557 (Python 3.7), tự động tạo ra các phương thức __init__, __repr__ và __eq__ từ các trường class được chú thích. Khi làm việc với JSON APIs, file cấu hình hoặc hàng đợi tin nhắn, dataclasses cung cấp cho dữ liệu một cấu trúc có kiểu mà các trình soạn thảo và công cụ kiểm tra kiểu như mypy có thể xác minh trong quá trình phát triển.

Hàm json.loads() của Python trả về các dict và list thông thường. Chúng hoạt động được, nhưng không có thông tin kiểu: một key viết sai trả về None thay vì báo lỗi, và trình soạn thảo không thể tự động hoàn thành tên trường. Dataclasses giải quyết vấn đề này bằng cách ánh xạ mỗi key JSON thành một trường có tên và có kiểu. Các đối tượng JSON lồng nhau trở thành các định nghĩa dataclass riêng biệt, mảng trở thành các chú thích List[T], và giá trị null trở thành Optional[T] với giá trị mặc định là None.

Viết các định nghĩa này bằng tay là công việc lặp đi lặp lại. Bạn phải đọc JSON, xác định kiểu của từng trường từ giá trị của nó, chuyển đổi key từ camelCase hoặc snake_case sang quy ước Python, và xử lý các trường hợp đặc biệt như trường nullable và mảng kiểu hỗn hợp. Một bộ chuyển đổi thực hiện tất cả điều này trong vài mili giây. Bạn dán JSON, nhận code dataclass chính xác và tiếp tục công việc.

Tại sao nên dùng bộ chuyển đổi JSON sang Python?

Chuyển đổi thủ công cấu trúc JSON thành định nghĩa class Python đồng nghĩa với việc đoán kiểu từ dữ liệu mẫu, sắp xếp lại trường để trường bắt buộc đứng trước trường tùy chọn, và cập nhật lại tất cả khi API thay đổi. Bộ chuyển đổi loại bỏ những trở ngại đó.

Tạo dataclass tức thì
Dán JSON và nhận các định nghĩa Python dataclass có kiểu trong chưa đến một giây. Đối tượng lồng nhau, danh sách và trường tùy chọn được xử lý tự động.
🔒
Xử lý ưu tiên bảo mật
Quá trình chuyển đổi chạy hoàn toàn trong trình duyệt bằng JavaScript. JSON của bạn không bao giờ rời khỏi thiết bị. API key, token và dữ liệu người dùng được giữ riêng tư.
📝
Type annotations chính xác
Mỗi trường được tạo đều có type annotation Python được suy ra từ giá trị JSON: str, int, float, bool, List[T] hoặc Optional[T] cho giá trị null.
📦
Không cần cài đặt hay đăng ký
Mở trang và dán JSON của bạn. Không cần môi trường Python, không cần cài gói pip, không cần tạo tài khoản.

Các trường hợp sử dụng JSON sang Python

Phát triển REST API Client
Tạo dataclasses từ mẫu phản hồi API. Dán JSON trả về từ endpoint REST bên thứ ba và nhận các class Python type-safe sẵn sàng dùng với requests hoặc httpx.
Mô hình Request/Response FastAPI
Bắt đầu từ hình dạng JSON payload và tạo định nghĩa dataclass. Chuyển đổi chúng sang Pydantic models để có validation tự động trong các route handler của FastAPI.
Schema cho Data Pipeline
Định nghĩa cấu trúc bản ghi có kiểu cho ETL pipeline. Dán một tin nhắn JSON mẫu từ Kafka, RabbitMQ hoặc SQS và tạo dataclasses ghi lại hình dạng dữ liệu dự kiến.
Phân tích file cấu hình
Chuyển file cấu hình JSON thành class Python có kiểu. Tải cấu hình bằng json.load(), sau đó tạo một đối tượng dataclass để có tự động hoàn thành và kiểm tra kiểu trong trình soạn thảo.
Tạo Test Fixture
Tạo fixture có kiểu từ dữ liệu JSON mẫu. Kỹ sư QA có thể dán ảnh chụp phản hồi API và tạo định nghĩa dataclass để dùng trong bộ kiểm thử pytest.
Học type annotations trong Python
Sinh viên có thể dán bất kỳ cấu trúc JSON nào và xem Python biểu diễn nó với type hints như thế nào. Code được tạo ra minh họa List, Optional, class lồng nhau và giá trị mặc định trong ngữ cảnh thực tế.

Bảng ánh xạ kiểu JSON sang Python

Mỗi giá trị JSON ánh xạ sang một type annotation Python cụ thể. Bảng dưới đây cho thấy bộ chuyển đổi dịch từng kiểu JSON như thế nào, với cú pháp module typing (Python 3.7+) và cú pháp tích hợp có sẵn từ Python 3.10 trở lên.

Kiểu JSONVí dụPython (typing)Python 3.10+
string"hello"strstr
number (integer)42intint
number (float)3.14floatfloat
booleantrueboolbool
nullnullOptional[str]str | None
object{"k": "v"}@dataclass classnested model
array of strings["a", "b"]List[str]list[str]
array of objects[{"id": 1}]List[Item]list[Item]
mixed array[1, "a"]List[Any]list[Any]

Tài liệu tham khảo Decorator Dataclass

Decorator @dataclass chấp nhận nhiều tham số thay đổi cách class được tạo hoạt động. Tài liệu này bao gồm các tùy chọn phù hợp nhất khi làm việc với dữ liệu được lấy từ JSON.

Decorator / TrườngHành viDùng khi
@dataclassGenerates __init__, __repr__, __eq__ from field annotationsStandard dataclasses
@dataclass(frozen=True)Makes instances immutable (hashable, no attribute reassignment)Config objects, dict keys
@dataclass(slots=True)Uses __slots__ for lower memory and faster attribute accessPython 3.10+, large datasets
@dataclass(kw_only=True)All fields require keyword arguments in __init__Python 3.10+, many fields
field(default_factory=list)Sets a mutable default without sharing state between instancesList/dict/set defaults

So sánh dataclass, Pydantic và TypedDict

Python có ba cách phổ biến để định nghĩa cấu trúc có kiểu từ JSON. Mỗi cách phù hợp với một trường hợp sử dụng khác nhau. Dataclasses là tùy chọn thư viện chuẩn không có phụ thuộc bên ngoài. Pydantic bổ sung validation tại runtime. TypedDict chú thích các dict thông thường mà không tạo class mới.

@dataclass
Thư viện chuẩn (Python 3.7+). Tạo ra __init__, __repr__ và __eq__. Không có validation tại runtime. Hoạt động với mypy và dataclasses-json để tuần tự hóa. Phù hợp nhất cho cấu trúc dữ liệu nội bộ nơi bạn kiểm soát đầu vào.
BaseModel (Pydantic)
Thư viện bên thứ ba. Validation kiểu và ràng buộc tại runtime. Phân tích JSON trực tiếp qua model_validate_json(). Lựa chọn tiêu chuẩn cho FastAPI, quản lý cấu hình và mọi code nhận đầu vào không tin cậy.
TypedDict
Thư viện chuẩn (Python 3.8+). Thêm type hints vào dict thông thường. Không tạo __init__ hay phương thức nào. Giá trị vẫn được truy cập như dict thông thường. Dùng khi bạn cần kiểm tra kiểu nhưng muốn giữ giao diện dict, ví dụ trong các codebase cũ.

Ví dụ code

Các ví dụ này cho thấy cách dùng dataclasses được tạo ra trong Python, cách tạo chúng theo chương trình từ JavaScript, và cách dùng các phương pháp thay thế như Pydantic và công cụ CLI.

Python (dataclasses)
from dataclasses import dataclass
from typing import List, Optional
import json

@dataclass
class Address:
    street: str
    city: str
    zip: str

@dataclass
class User:
    id: int
    name: str
    email: str
    active: bool
    score: float
    address: Address
    tags: List[str]
    metadata: Optional[str] = None

raw = '{"id":1,"name":"Alice","email":"alice@example.com","active":true,"score":98.5,"address":{"street":"123 Main St","city":"Springfield","zip":"12345"},"tags":["admin","user"],"metadata":null}'
data = json.loads(raw)

# Reconstruct nested objects manually
addr = Address(**data["address"])
user = User(**{**data, "address": addr})
print(user.name)     # -> Alice
print(user.address)  # -> Address(street='123 Main St', city='Springfield', zip='12345')
JavaScript (generate Python from JSON)
// Minimal JSON-to-Python-dataclass generator in JS
function jsonToPython(obj, name = "Root") {
  const classes = [];
  function infer(val, fieldName) {
    if (val === null) return "Optional[str]";
    if (typeof val === "string") return "str";
    if (typeof val === "number") return Number.isInteger(val) ? "int" : "float";
    if (typeof val === "boolean") return "bool";
    if (Array.isArray(val)) {
      const first = val.find(v => v !== null);
      return first ? `List[${infer(first, fieldName + "Item")}]` : "List[Any]";
    }
    if (typeof val === "object") {
      const clsName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
      build(val, clsName);
      return clsName;
    }
    return "Any";
  }
  function build(obj, cls) {
    const fields = Object.entries(obj).map(([k, v]) => `    ${k}: ${infer(v, k)}`);
    classes.push(`@dataclass\nclass ${cls}:\n${fields.join("\n")}`);
  }
  build(obj, name);
  return classes.join("\n\n");
}

const data = { id: 1, name: "Alice", scores: [98, 85] };
console.log(jsonToPython(data, "User"));
// @dataclass
// class User:
//     id: int
//     name: str
//     scores: List[int]
Python (Pydantic BaseModel alternative)
from pydantic import BaseModel
from typing import List, Optional

class Address(BaseModel):
    street: str
    city: str
    zip: str

class User(BaseModel):
    id: int
    name: str
    email: str
    active: bool
    score: float
    address: Address
    tags: List[str]
    metadata: Optional[str] = None

# Pydantic parses and validates JSON in one step
raw = '{"id":1,"name":"Alice","email":"alice@example.com","active":true,"score":98.5,"address":{"street":"123 Main St","city":"Springfield","zip":"12345"},"tags":["admin","user"],"metadata":null}'
user = User.model_validate_json(raw)
print(user.name)              # -> Alice
print(user.model_dump_json()) # -> re-serializes to JSON
CLI (datamodel-code-generator)
# Install the generator
pip install datamodel-code-generator

# Generate dataclasses from a JSON file
datamodel-codegen --input data.json --output models.py --output-model-type dataclasses.dataclass

# Generate Pydantic models instead
datamodel-codegen --input data.json --output models.py

# From a JSON string via stdin
echo '{"id": 1, "name": "Alice", "tags": ["admin"]}' | \
  datamodel-codegen --output-model-type dataclasses.dataclass
# Output:
# @dataclass
# class Model:
#     id: int
#     name: str
#     tags: List[str]

Câu hỏi thường gặp

Sự khác biệt giữa Python dataclass và class thông thường là gì?
Dataclass dùng decorator @dataclass để tự động tạo các phương thức __init__, __repr__ và __eq__ từ các chú thích trường. Class thông thường yêu cầu bạn tự viết các phương thức này. Dataclasses giảm code lặp khi class chủ yếu chứa dữ liệu, đây là trường hợp điển hình cho các cấu trúc lấy từ JSON.
Tôi có thể dùng dataclasses với tuần tự hóa JSON trực tiếp không?
Module json của thư viện chuẩn không thể tuần tự hóa các đối tượng dataclass theo mặc định. Dùng dataclasses.asdict() để chuyển đổi dataclass thành dict, sau đó truyền vào json.dumps(). Để có thêm tùy chỉnh, thư viện dataclasses-json bổ sung các phương thức .to_json() và .from_json(), còn Pydantic models xử lý tuần tự hóa ngay từ đầu.
Bộ chuyển đổi xử lý các đối tượng JSON lồng nhau như thế nào?
Mỗi đối tượng lồng nhau trở thành một định nghĩa @dataclass riêng biệt. Nếu một trường JSON tên "address" chứa đối tượng có "street" và "city", bộ chuyển đổi tạo ra dataclass Address và chú thích trường cha là address: Address. Các cấu trúc lồng nhau sâu tạo ra nhiều định nghĩa dataclass theo thứ tự phụ thuộc.
Điều gì xảy ra khi một trường JSON là null?
Các trường null được chú thích là Optional[str] (hoặc kiểu phù hợp nếu có thể suy ra từ ngữ cảnh) với giá trị mặc định là None. Các trường có giá trị mặc định phải đứng sau các trường bắt buộc trong dataclass, nên bộ chuyển đổi đặt các trường tùy chọn ở cuối định nghĩa class.
Có sự khác biệt giữa dataclasses và Pydantic models cho JSON không?
Dataclasses là một phần của thư viện chuẩn và không validation dữ liệu tại runtime. Pydantic models validation kiểu, áp dụng ràng buộc và có thể phân tích chuỗi JSON thô trực tiếp. Nếu bạn nhận JSON từ nguồn bên ngoài và cần từ chối dữ liệu không hợp lệ, Pydantic phù hợp hơn. Để truyền dữ liệu nội bộ nơi bạn tin tưởng đầu vào, dataclasses nhẹ hơn và không có phụ thuộc bên ngoài.
Làm thế nào để xử lý key JSON dạng camelCase trong Python dataclasses?
Quy ước Python dùng snake_case cho tên biến. Bộ chuyển đổi dịch key camelCase như "firstName" thành trường snake_case như first_name. Nếu bạn cần phân tích ngược từ JSON, dùng thư viện dataclasses-json với cấu hình ánh xạ giữa hai quy ước đặt tên, hoặc viết phương thức __post_init__ tùy chỉnh.
Bộ chuyển đổi có hỗ trợ cú pháp Python 3.10+ như list[str] thay vì List[str] không?
Bộ chuyển đổi tạo ra các import module typing (List, Optional) để đảm bảo tương thích tối đa với Python 3.7 đến 3.12. Nếu dự án của bạn hướng đến Python 3.10 trở lên, bạn có thể thay thế List[str] bằng list[str] và Optional[str] bằng str | None. Bảng ánh xạ kiểu ở trên hiển thị cả hai dạng.