1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python初心者】dataclassを辞書やJSONに変換する方法(asdictとシリアライズ)

Posted at

前回の記事では、@dataclass を使って __init__() を自動生成する仕組みや、コンストラクター引数の扱いについてまとめました。
今回はその続きとして、dataclassインスタンスを辞書に変換する方法(asdict()や、JSONとして保存・送信する方法(シリアライズ)について、自分の理解を整理しておきます。

辞書に変換する:asdict()

まず、dataclass を辞書に変換したいときは、標準ライブラリ dataclassesasdict() を使います。

from dataclasses import dataclass, asdict

@dataclass
class User:
    name: str
    age: int

user = User("Riku", 28)
user_dict = asdict(user)
print(user_dict)  # {'name': 'Riku', 'age': 28}

ポイント:

  • asdict()再帰的に変換されるので、入れ子になった dataclass も対応してくれます。
  • 返り値は Python の通常の辞書(dict 型)になります。

JSONに変換する(シリアライズ)

Pythonの辞書を JSON に変換するには、標準ライブラリの json.dumps() を使います。
つまり、asdict() と組み合わせることで dataclass も JSON に変換できます。

import json
from dataclasses import dataclass, asdict

@dataclass
class Product:
    name: str
    price: int

p = Product("Headphones", 15000)

# 辞書に変換してからJSONに変換
json_str = json.dumps(asdict(p), ensure_ascii=False)
print(json_str)  # {"name": "Headphones", "price": 15000}

ensure_ascii=False を使うと、日本語なども文字化けせずに表示されます。

ネストされた dataclass にも対応できる

入れ子構造(ネスト)になった dataclass も、asdict() で辞書に変換できます。

from dataclasses import dataclass, asdict

@dataclass
class Author:
    name: str
    age: int

@dataclass
class Book:
    title: str
    author: Author

b = Book("Python入門", Author("Suzuki", 40))
print(asdict(b))
# {'title': 'Python入門', 'author': {'name': 'Suzuki', 'age': 40}}

asdict() は内部の dataclass も自動的に辞書化してくれます。

JSONから復元(逆変換)するには?

Pythonの辞書から dataclass インスタンスを作りたいときは、**辞書展開 を使います。

from dataclasses import dataclass

@dataclass
class Item:
    id: int
    name: str

item_dict = {"id": 1, "name": "Monitor"}
item = Item(**item_dict)
print(item)  # Item(id=1, name='Monitor')

もし JSON 文字列から復元したい場合は、まず json.loads() で辞書にしてから展開します。

import json
from dataclasses import dataclass

@dataclass
class Item:
    id: int
    name: str

json_str = '{"id": 1, "name": "Monitor"}'
item_data = json.loads(json_str)
item = Item(**item_data)
print(item)  # Item(id=1, name='Monitor')

ネストが深くなると、自分で中身を展開してあげる必要が出てきますが、シンプルなケースでは ** 展開で十分です。

まとめ

  • asdict() を使えば、dataclass を辞書に変換できる
  • json.dumps() で JSON 文字列として保存・送信できる
  • JSON → 辞書 → dataclass への復元には json.loads()**kwargs を使う
  • ネスト構造も asdict() で自動変換されるので扱いやすい
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?