Python bài 20: Serialization với JSON và pickle
- 18-10-2026
- Toanngo92
- 0 Comments
Giáo trình Python miễn phí · Chương 10/12: Tệp và serialization · Bài 20/24.
Mục lục
Mục tiêu bài học
Chuyển dữ liệu thành dạng lưu/truyền được, đọc lại đúng cấu trúc và biết giới hạn của JSON, pickle.
Serialization và deserialization
Serialization biến dữ liệu trong chương trình thành biểu diễn có thể lưu hoặc truyền; deserialization khôi phục dữ liệu từ biểu diễn đó. JSON phù hợp trao đổi giữa nhiều ngôn ngữ, pickle gắn với đối tượng Python và có yêu cầu tin cậy riêng.
json.dumps() trả chuỗi; json.loads() nhận chuỗi. json.dump()/load() làm việc với đối tượng tệp. JSON dùng true, false, null, còn Python dùng True, False, None; thư viện chuyển đổi tương ứng. Không dùng eval() để đọc JSON hoặc dữ liệu người khác gửi.
import json
from pathlib import Path
hoc_vien = {"ten": "Nguyễn An", "diem": [8, 9], "dang_hoc": True}
chuoi = json.dumps(hoc_vien, ensure_ascii=False)
print(chuoi)
du_lieu = json.loads(chuoi)
print(du_lieu["ten"])
tep = Path("hoc_vien_demo.json")
with tep.open("w", encoding="utf-8") as f:
json.dump(hoc_vien, f, ensure_ascii=False, indent=2)
with tep.open(encoding="utf-8") as f:
doc_lai = json.load(f)
print(doc_lai == hoc_vien)
Kết quả:
{"ten": "Nguyễn An", "diem": [8, 9], "dang_hoc": true}
Nguyễn An
True
Kiểm tra cấu trúc sau khi đọc
JSON hợp lệ cú pháp chưa chắc hợp lệ theo nghiệp vụ. Có thể nhận list trong khi chương trình cần dict, hoặc điểm dạng chuỗi. Kiểm tra kiểu, khóa bắt buộc và khoảng giá trị sau khi parse. JSONDecodeError không thay cho validation nội dung.
JSON không trực tiếp biểu diễn set, datetime hoặc đối tượng lớp tùy ý. Tuple trở thành JSON array và đọc lại là list. Khóa object của JSON là chuỗi. Nếu cần giữ kiểu đặc biệt, thiết kế quy ước rõ ràng, ví dụ ngày theo định dạng ISO 8601.
import json
def doc_ten(text):
data = json.loads(text)
if not isinstance(data, dict):
raise ValueError("Cần một JSON object")
ten = data.get("ten")
if not isinstance(ten, str) or not ten.strip():
raise ValueError("Thiếu tên hợp lệ")
return ten.strip()
print(doc_ten('{"ten": " An "}'))
Kết quả:
An
Pickle chỉ dành cho nguồn tin cậy
pickle có thể lưu nhiều kiểu đối tượng Python hơn JSON, nhưng nạp pickle có thể thực thi mã. Chỉ unpickle dữ liệu do bạn kiểm soát và tin cậy; không nạp tệp đính kèm, dữ liệu upload hoặc phản hồi mạng chưa được tin cậy. Nhị phân không đồng nghĩa với mã hóa hoặc bảo mật.
import pickle
# Dữ liệu do chính chương trình tạo trong ví dụ này.
blob = pickle.dumps({"diem": [8, 9]})
ban_sao = pickle.loads(blob)
print(ban_sao["diem"])
Kết quả:
[8, 9]
Lỗi thường gặp và lưu ý
- ensure_ascii=False giữ chữ tiếng Việt dễ đọc trong JSON; tệp vẫn cần encoding UTF-8.
- Không dùng pickle như định dạng trao đổi công khai giữa các hệ thống; chọn JSON khi đáp ứng yêu cầu dữ liệu.
Ghi nhớ
Chọn định dạng theo đối tượng trao đổi và mức tin cậy. Phân biệt parse thành công với dữ liệu hợp lệ, quản lý lỗi tệp và lỗi định dạng riêng.
