【ヒント】Python ミキシン - JsonSerializableMixin
By khoanc, at: 2025年3月1日17:40
Estimated Reading Time: __READING_TIME__ minutes
![[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
全ての属性を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}
=> 高速でシンプル
しかし、入れ子になったオブジェクトや特殊な型は処理できません。
2. カスタムフィールドホワイトリスト
特定のフィールド(__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 # 除外
print(User("Joe", "[email protected]", "amazing Python team").to_json())
# {"username": "Joe", "email": "[email protected]"}
=> セキュリティに最適(パスワード、トークンなどの非表示)。
3. ネストされたオブジェクトのサポート
to_json()
または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"}]}
=> 実際のオブジェクトグラフを処理します。
4. JSONではない型のカスタムエンコーダ
datetime、Decimal、その他の特殊な型をサポートします
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"}
=> 通常のjson.dumpsを壊してしまうような現実世界のデータ型でも機能します。