こんにちは。
はけです。
python3.7から使えるようになったdataclass。
データの箱を示すクラスを用意するときにとても重宝します。
本記事は、次のような方を対象にしています。
- dataclassをdictやjsonに変換したい!
- jsonやdictをdataclassに変換したい!
dataclassのデータを使って処理を行うときや、出力用のフォーマットに整形するようなとき、データの変換を行う必要があります。
そんなデータの変換について、本記事ではdictや jsonへ相互に変換する方法を解説します。
特に、json形式のリクエストをAPIで受け取るときや、DBから情報を取得するときに使用します。
覚えてしまえば簡単にできてしまいます。
ぜひ試してみてくださいね!
目次
pythonのdataclassをdictやjsonに相互変換する
dataclassをdictやjsonに相互変換する方法を解説していきます。
実行環境
- Windows10
- python3.9.1
- dataclasses-json0.5.2
dataclassを使う理由
dataclassはpython3.7から使えるようになり、データの箱を表現するためにとても便利なクラスです。
たくさんメリットがありますが、大きなメリットは次になります。
- クラスがデータの箱であることが明示できる
- クラスの初期化を簡単に実装できる
本記事ではあまり詳しいことは書きませんが、データの箱としてかなり優秀なクラスがdataclassになります。
今回のサンプルプログラムではjsonやdictなどのデータがネストできることも考慮し、ネストしたdataclassで試しています。
from dataclasses import dataclass, field from typing import List @dataclass class SampleInfoChild: """ Sample情報子データクラス """ childint: int = 0 childstr: str = '' @dataclass class SampleInfoParent: """ Sample情報親データクラス """ data1: int = 0 data2: str = '' data3: float = 0.0 listint: List[int] = field(default_factory=list) childobj: SampleInfoChild = None
SampleInfoParentがメインのクラス、SampleInfoChildがネストされたクラスになります。
それぞれのクラスの頭に「@dataclass」をつけることでdataclassであることを定義できます。
childobjにSampleInfoChild型を設定することでネストしたクラスを定義することができます。
では、さっそくdataclassの変換方法を解説していきます!
dataclassをdictに変換する方法
まずはdataclassをdictに変換する方法を解説していきます。
dataclassをdictに変換するときは標準機能に搭載されているdataclassesのasdictを使用します。
from dataclasses import dataclass, field, asdict from typing import List @dataclass class SampleInfoChild: """ Sample情報子データクラス """ childint: int = 0 childstr: str = '' @dataclass class SampleInfoParent: """ Sample情報親データクラス """ data1: int = 0 data2: str = '' data3: float = 0.0 listint: List[int] = field(default_factory=list) childobj: SampleInfoChild = None sample = SampleInfoParent(2, 'abc', 2.5, [123, 234], SampleInfoChild(2, 'ddd')) print(asdict(sample)) # ★
単純にSampleInfoParentクラスを初期化後、asdictでdictに変換しています。
結果を見てみると、次のようになります。
{'data1': 2, 'data2': 'abc', 'data3': 2.5, 'listint': [123, 234], 'childobj': {'childint': 2, 'childstr': 'ddd'}}
しっかりすべての変数が変換できていることがわかります。
このように、簡単にdictに変換することができます。
dictからdataclassに変換する方法
次はdictからdataclassに変換する方法を解説していきます。
dictからdataclassに変換するときは、dictを展開することで初期化することができます。
from dataclasses import dataclass, field from typing import List @dataclass class SampleInfoChild: """ Sample情報子データクラス """ childint: int = 0 childstr: str = '' @dataclass class SampleInfoParent: """ Sample情報親データクラス """ data1: int = 0 data2: str = '' data3: float = 0.0 listint: List[int] = field(default_factory=list) childobj: SampleInfoChild = None dict = {'data1':2, 'data2':'abc', 'data3':2.5, 'listint':[123, 234], 'childobj': {'childint':2, 'childstr':'ddd'}} sample = SampleInfoParent(**dict) # ★ print(sample)
dictを作成しておきます。キー名やネストの構成は同じにする必要があります。
**dictをクラスの初期化時に渡すことで、変換が実現できます。
結果を見てみると、次のようになります。
SampleInfoParent(data1=2, data2='abc', data3=2.5, listint=[123, 234], childobj={'childint': 2, 'childstr': 'ddd'})
クラスの情報がすべて作成されています。
dataclassをjsonに変換する方法
次はdataclassをjsonに変換する方法を解説していきます。
jsonに変換するときに、外部ライブラリのdataclasses-jsonが必要になります。
以下のコマンドでライブラリをインストールしてください。
pip install dataclasses-json
インストールができたら、次のようにto_jsonを使用してdataclassをjsonに変換することができます。
from dataclasses import dataclass, field from typing import List from dataclasses_json import dataclass_json # ★ @dataclass_json # ★ @dataclass class SampleInfoChild: """ Sample情報子データクラス """ childint: int = 0 childstr: str = '' @dataclass_json # ★ @dataclass class SampleInfoParent: """ Sample情報親データクラス """ data1: int = 0 data2: str = '' data3: float = 0.0 listint: List[int] = field(default_factory=list) childobj: SampleInfoChild = None sample = SampleInfoParent(2, 'abc', 2.5, [123, 234], SampleInfoChild(2, 'ddd')) print(sample) print(sample.to_json(indent=4, ensure_ascii=False)) # ★
★部分が変更箇所になります。
以下のような実装を加えました。
- dataclasses_jsonをimportしました
- 各dataclassに@dataclass_jsonのデコレータを加えました
- 最後にto_jsonでjson文字列に変換しました
結果を見てみると、次のようになります。
{ "data1": 2, "data2": "abc", "data3": 2.5, "listint": [ 123, 234 ], "childobj": { "childint": 2, "childstr": "ddd" } }
json形式の文字列が出力されます。
jsonからdataclassに変換する方法
最後にjsonからdataclassに変換する方法を解説していきます。
次のようにfrom_jsonを使用してjsonからdataclasssに変換することができます。
from dataclasses import dataclass, field from typing import List from dataclasses_json import dataclass_json @dataclass_json @dataclass class SampleInfoChild: """ Sample情報子データクラス """ childint: int = 0 childstr: str = '' @dataclass_json @dataclass class SampleInfoParent: """ Sample情報親データクラス """ data1: int = 0 data2: str = '' data3: float = 0.0 listint: List[int] = field(default_factory=list) childobj: SampleInfoChild = None jsonstr = '''{"data1":2, "data2":"abc", "data3":2.5, "listint":[123, 234], "childobj": {"childint":2, "childstr":"ddd"}}''' sample = SampleInfoParent.from_json(jsonstr) # ★ print(sample)
★部分が変更箇所になります。
dataclass.from_jsonでjsonからdataclassに変換することができます。
結果を見てみると、次のようになります。
SampleInfoParent(data1=2, data2='abc', data3=2.5, listint=[123, 234], childobj=SampleInfoChild(childint=2, childstr='ddd'))
しっかりとdataclassの情報が取り込まれました。
以上が、dataclassからdictやjsonを相互変換する方法の解説となります。
まとめ
本記事では以下のことを解説しました。
- dataclassからdictに変換する方法
- dictからdataclassに変換する方法
- dataclassからjsonに変換する方法
- jsonからdataclassに変換する方法
jsonを相互変換する場合は、「dataclasses-json」を取り込むことで変換することができるようになりました。
ぜひ参考に、dataclassを使ってみてください!
以上がdataclassをdictやjsonと相互に変換する方法となります。
本ブログでは、主にPythonの環境設定やコーディングの方法について、初心者~中級者向けに解説しています。
興味がある方は、他の記事も参考にしてみてください!!