[MẸO] Mixin Python - JsonSerializableMixin
By khoanc, at: 17:40 Ngày 01 tháng 3 năm 2025
Thời gian đọc ước tính: __READING_TIME__ phút
![[TIPS] Python Mixins - JsonSerializableMixin](/media/filer_public_thumbnails/filer_public/0e/b1/0eb177a5-4044-4961-bdbb-3b8e55218f35/tips_python_mixins_-_jsonserializablemixin.png__1500x900_crop_subsampling-2_upscale.png)
![[TIPS] Python Mixins - JsonSerializableMixin](/media/filer_public_thumbnails/filer_public/0e/b1/0eb177a5-4044-4961-bdbb-3b8e55218f35/tips_python_mixins_-_jsonserializablemixin.png__400x240_crop_subsampling-2_upscale.png)
1. Basic JsonSerializableMixin
Nhanh chóng đưa tất cả thuộc tính vào JSON
import json
class JsonSerializableMixin:
def to_json(self):
return json.dumps(vars(self))
class Product(JsonSerializableMixin):
def __init__(self, name, price):
self.name = name
self.price = price
print(Product("Laptop", 1200).to_json())
# {"name": "Laptop", "price": 1200}
=> Nhanh và đơn giản
NHƯNG: Không xử lý các đối tượng lồng nhau hoặc các kiểu dữ liệu đặc biệt.
2. Danh sách trắng trường tùy chỉnh
Chỉ bao gồm các trường cụ thể (__json_fields__
)
import json
class JsonWhitelistMixin:
__json_fields__ = []
def to_json(self):
data = {field: getattr(self, field) for field in self.__json_fields__ if hasattr(self, field)}
return json.dumps(data)
class User(JsonWhitelistMixin):
__json_fields__ = ["username", "email"]
def __init__(self, username, email, password):
self.username = username
self.email = email
self.password = password # bị loại trừ
print(User("Joe", "[email protected]", "amazing Python team").to_json())
# {"username": "Joe", "email": "[email protected]"}
=> Tuyệt vời cho bảo mật (ẩn mật khẩu, token, v.v.).
3. Hỗ trợ đối tượng lồng nhau
Xử lý danh sách, từ điển và các đối tượng khác với to_json()
hoặc to_dict()
import json
class JsonNestedMixin:
def to_dict(self):
def convert(obj):
if isinstance(obj, list):
return [convert(i) for i in obj]
if isinstance(obj, dict):
return {k: convert(v) for k, v in obj.items()}
if hasattr(obj, "to_dict"):
return obj.to_dict()
return obj
return {k: convert(v) for k, v in vars(self).items()}
def to_json(self):
return json.dumps(self.to_dict())
class Address(JsonNestedMixin):
def __init__(self, city, country):
self.city = city
self.country = country
class Person(JsonNestedMixin):
def __init__(self, name, addresses):
self.name = name
self.addresses = addresses
p = Person("Glinteco", [Address("Hanoi", "Vietnam"), Address("Melbourne", "Australia")])
print(p.to_json())
# {"name": "Glinteco", "addresses": [{"city": "Hanoi", "country": "Vietnam"}, {"city": "Melbourne", "country": "Australia"}]}
=> Xử lý đồ thị đối tượng trong thế giới thực.
4. Bộ mã hóa tùy chỉnh cho các kiểu dữ liệu không phải JSON
Hỗ trợ datetime, Decimal, hoặc các kiểu dữ liệu đặc biệt khác
import json, datetime, decimal
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
if isinstance(obj, decimal.Decimal):
return float(obj)
return super().default(obj)
class JsonCustomEncoderMixin:
def to_json(self):
return json.dumps(vars(self), cls=CustomEncoder)
class Invoice(JsonCustomEncoderMixin):
def __init__(self, amount, issued_at):
self.amount = decimal.Decimal(amount)
self.issued_at = issued_at
print(Invoice("1200.50", datetime.datetime(2025, 9, 6, 14, 30)).to_json())
# {"amount": 1200.5, "issued_at": "2025-09-06T14:30:00"}
=> Hoạt động với các kiểu dữ liệu trong thế giới thực làm hỏng vanilla json.dumps.