
Tuần tự hóa dữ liệu hiệu quả với JSON và các kiểu dữ liệu tùy chỉnh
Bài viết này hướng dẫn phương pháp xây dựng một quy trình tuần tự hóa JSON (JSON serialization pipeline) tối ưu trong Python, có khả năng xử lý các kiểu dữ liệu tùy chỉnh, khắc phục sự cố linh hoạt và...
Chuẩn hóa tuần tự hóa dữ liệu với JSON và các kiểu dữ liệu tùy chỉnh
Tác giả: Iván Palomares Carrascosa, ngày 26/10/2026, chuyên mục Practical Python 0
Chia sẻ
Đăng bài
Chia sẻ
Bài viết này hướng dẫn phương pháp xây dựng quy trình tuần tự hóa JSON hiệu quả trong Python, hỗ trợ xử lý các kiểu dữ liệu tùy chỉnh, khôi phục lỗi linh hoạt và điều chỉnh cấu trúc dữ liệu (schema migrations).
Các nội dung chính bao gồm:
Cách định nghĩa bộ mã hóa JSON tùy chỉnh nhằm xử lý các kiểu dữ liệu trong Python như datetime, set, Path và Enum.
Cách xây dựng hàm giải mã tùy chỉnh để tái tạo các đối tượng Python ban đầu từ chuỗi JSON đã tuần tự hóa, bao gồm cả cơ chế xử lý dữ liệu sai định dạng.
Cách quản lý các thay đổi về cấu trúc dữ liệu theo thời gian thông qua hàm khởi tạo (factory function), áp dụng giá trị mặc định và thực hiện chuyển đổi cấu trúc trong quá trình giải tuần tự hóa.
Giới thiệu và bối cảnh
Trong quá trình xây dựng các quy trình học máy (machine learning), thời gian dành cho việc thiết kế kiến trúc mô hình thường chỉ chiếm một phần nhỏ. Phần lớn thời lượng còn lại được sử dụng cho việc xử lý dữ liệu: bao gồm làm sạch, tiền xử lý và chuyển đổi dữ liệu nhằm đáp ứng định dạng chuẩn cho các mô hình tiếp theo.
Bài viết này giải quyết một vấn đề quan trọng thường gặp trong kỹ thuật học máy: nhu cầu liên tục luân chuyển các tập dữ liệu có cấu trúc giữa các tệp tin, tiến trình, dịch vụ vi mô (microservices) và API. Trong toàn bộ các quá trình này, việc sở hữu một giải pháp tuần tự hóa và giải tuần tự hóa dữ liệu bảo đảm độ tin cậy và chuẩn xác là yêu cầu bắt buộc.
Bài viết sẽ phân tích các chiến lược thực tiễn nhằm tuần tự hóa các kiểu dữ liệu tùy chỉnh, cho phép phân tích cú pháp ngược lại một cách an toàn, quản lý các thay đổi của cấu trúc dữ liệu và xử lý dữ liệu sai định dạng mà không làm gián đoạn toàn bộ quy trình.
Trước khi đi sâu vào giải pháp ba bước, cần xem xét nguyên nhân cốt lõi: các hạn chế của định dạng JSON khi xử lý một số kiểu dữ liệu như datetime, set, Path hoặc Enum. Giả định cấu hình thử nghiệm học máy như sau:
from datetime import datetime
from enum import Enum
from pathlib import Path
import json
class ModelType(Enum):
RANDOM_FOREST = "rf"
NEURAL_NET = "nn"
experiment_config = {
"experiment_id": 1042,
"model_type": ModelType.NEURAL_NET,
"features": {"age", "income", "location"}, # Kiểu set!
"data_path": Path("/data/v2/train.csv"),
"timestamp": datetime.now(),
"nested_meta": {
"retries": 3
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from datetime import datetime
from enum import Enum
from pathlib import Path
import json
class ModelType(Enum):
RANDOM_FOREST = "rf"
NEURAL_NET = "nn"
experiment_config = {
"experiment_id": 1042,
"model_type": ModelType.NEURAL_NET,
"features": {"age", "income", "location"}, # Kiểu set!
"data_path": Path("/data/v2/train.csv"),
"timestamp": datetime.now(),
"nested_meta": {
"retries": 3
}
}
Khi tiến hành tuần tự hóa cấu hình thử nghiệm này bằng lệnh json.dumps(experiment_config), hệ thống sẽ xuất hiện thông báo lỗi:
TypeError: Object of type ModelType is not JSON serializable
1
TypeError: Object of type ModelType is not JSON serializable
Những lỗi phát sinh này sẽ được xử lý bằng cách thiết lập một quy trình mã hóa và giải mã chuẩn xác cho các đối tượng JSON có kiểu dữ liệu tùy chỉnh.
1. Định nghĩa bộ mã hóa tùy chỉnh
Trước hết, cần định nghĩa một lớp mã hóa (encoder class) tùy chỉnh kế thừa từ json.JSONEncoder. Bước này đóng vai trò then chốt nhằm “tùy biến” hàm json.dumps() hiện hành bằng logic bổ sung được triển khai trong lớp, qua đó xử lý các kiểu dữ liệu tùy chỉnh mà định dạng JSON mặc định không hỗ trợ.
Bên cạnh việc kế thừa json.JSONEncoder, phương thức default() cũng cần được ghi đè (override). Tại đây, quy trình xử lý tùy chỉnh cho từng kiểu dữ liệu cụ thể sẽ lần lượt được thiết lập thông qua các câu lệnh điều kiện có dạng if isinstance(obj, DATA_TYPE):, trong đó DATA_TYPE được thay thế bằng kiểu dữ liệu hoặc tên lớp tương ứng, như minh họa dưới đây:
class RobustEncoder(json.JSONEncoder):
def default(self, obj):
# Handling Datetimes
if isinstance(obj, datetime):
return {"__type__": "datetime", "value": obj.isoformat()}
# Handling Sets (convert to list for JSON)
if isinstance(obj, set):
return {"__type__": "set", "value": list(obj)}
# Handling Paths (convert to string)
if isinstance(obj, Path):
return {"__type__": "path", "value": str(obj)}
# Handling Enums (extract the underlying value)
if isinstance(obj, Enum):
return obj.value
# Letting the base class handle everything else (or raise TypeError)
return super().default(obj)
# Serializing our config object
json_string = json.dumps(experiment_config, cls=RobustEncoder, indent=2)
print(json_string)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class RobustEncoder(json.JSONEncoder):
def default(self, obj):
# Handling Datetimes
if isinstance(obj, datetime):
return {"__type__": "datetime", "value": obj.isoformat()}
# Handling Sets (convert to list for JSON)
if isinstance(obj, set):
return {"__type__": "set", "value": list(obj)}
# Handling Paths (convert to string)
if isinstance(obj, Path):
return {"__type__": "path", "value": str(obj)}
# Handling Enums (extract the underlying value)
if isinstance(obj, Enum):
return obj.value
# Letting the base class handle everything else (or raise TypeError)
return super().default(obj)
# Serializing our config object
json_string = json.dumps(experiment_config, cls=RobustEncoder, indent=2)
print(json_string)
Một chi tiết quan trọng khác: kỹ thuật bổ sung giúp quá trình tuần tự hóa (serialization) đạt độ chuẩn xác cao trong đoạn mã trên là việc gắn nhãn định danh __type__ vào các đối tượng có nguy cơ mất kiểu dữ liệu gốc khi chuyển đổi sang các kiểu dữ liệu nguyên thủy của JSON. Trường hợp này xuất hiện khi chuyển đổi cấu trúc set trong Python sang dạng list.
Cần lưu ý cách tham số cls=RobustEncoder được đưa vào lệnh gọi json.dumps() để kích hoạt bộ mã hóa tùy chỉnh.
Kết quả:
{
"experiment_id




Nguồn tin: Machine Learning Mastery — Tác giả: Iván Palomares Carrascosa. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.