こんにちは。
はけです。
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の環境設定やコーディングの方法について、初心者~中級者向けに解説しています。
興味がある方は、他の記事も参考にしてみてください!!