[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
[TIPS] Python Mixins - JsonSerializableMixin

 

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.

 

Tag list:

Theo dõi

Theo dõi bản tin của chúng tôi và không bao giờ bỏ lỡ những tin tức mới nhất.