Python学習チャンネル by PyQ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

Pythonのdataclassのオブジェクトと辞書の相互変換

こんにちは、PyQチームです。今回はPythonのdataclassオブジェクトと辞書の相互変換について紹介します。

Pythonのdataclassのオブジェクトと辞書の相互変換

辞書は、任意の文字列をキーとして使えますが、キーの名称を固定できた方が便利なことがあります。
その方法として、下記のようにdataclassesモジュールのdataclassが使えます。

from dataclasses import dataclass, asdict

@dataclass
class Author:
    name: str

author1 = Author(name="夏目漱石")
print(author1)

実行結果

Author(name='夏目漱石')

name: strstrのような書き方を型ヒントといいます。dataclassは型ヒントを使うことが特徴です。
また、このdataclassのオブジェクト(author1)は、次のようにasdict()を使って辞書に変換できます。

dct = asdict(author1)
print(dct)

実行結果

{'name': '夏目漱石'}

逆に、辞書からdataclassのオブジェクトを作成できます。

print(Author(**dct))

実行結果

Author(name='夏目漱石')

このように、dataclassのオブジェクトと辞書を相互変換できますが、ネストしている(入れ子になっている)要素は、辞書からオブジェクトになりません。ネストのクラスを使って確認してみましょう。

@dataclass
class Book:
    title: str
    authors: list[Author]

book1 = Book(title="坊っちゃん", authors=[author1])
print(book1)
dct = asdict(book1)
print(dct)
print(Book(**dct))

実行結果

Book(title='坊っちゃん', authors=[Author(name='夏目漱石')])
{'title': '坊っちゃん', 'authors': [{'name': '夏目漱石'}]}
Book(title='坊っちゃん', authors=[{'name': '夏目漱石'}])

上記のように、Book(**dct)authorsの要素が辞書のままです。

pydanticモジュールのdataclassを使った相互変換

本ブログでは、ネストしていても相互変換になる方法を紹介します。
その方法は、dataclassesモジュールではなく、pydanticモジュールのdataclassを使う方法です。
pydanticは、型ヒントを使ってデータのバリデーションなどをサポートする、サードパーティ製のライブラリです。

docs.pydantic.dev

実際に確認してみましょう。下記は、インポート文以外は先ほどと同じ記述ですが、辞書から変換したauthorsの要素がAuthorになっています。

from pydantic.dataclasses import dataclass

@dataclass
class Author:
    name: str

@dataclass
class Book:
    title: str
    authors: list[Author]

author1 = Author(name="夏目漱石")
book1 = Book(title="坊っちゃん", authors=[author1])

print(book1)
dct = asdict(book1)
print(dct)
print(Book(**dct))

実行結果

Book(title='坊っちゃん', authors=[Author(name='夏目漱石')])
{'title': '坊っちゃん', 'authors': [{'name': '夏目漱石'}]}
Book(title='坊っちゃん', authors=[Author(name='夏目漱石')])

pydanticモジュールのバリデーション

pydanticモジュールのdataclassは、dataclassesモジュールのdataclassと同様に使えますが、型ヒントを使ってバリデーションも行います。
たとえば、下記を実行すると、タイトルが文字列ではなく整数のため、ValidationErrorになります(dataclassesモジュールではエラーになりません)。つまり、間違ったデータが入ると気づきやすくなります。
このように、pydanticは主にバリデーションを目的として使われることが多いです。

dct = {"title": 0, "authors": []}
print(Book(**dct))

実行結果

---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
(中略)
ValidationError: 1 validation error for Book
title
  Input should be a valid string [type=string_type, input_value=0, input_type=int]
    For further information visit https://errors.pydantic.dev/2.6/v/string_type

なお、pydanticモジュールは(dataclassesモジュールと違って)標準モジュールではないため、下記のようにインストールが必要です。

pip install pydantic

まとめ

  • pydanticモジュールのdataclass、あるいは、dataclassesモジュールのdataclassを使うと、オブジェクトと辞書を相互に変換できます。
    • ただし、dataclassesモジュールでは、ネストしていると辞書から適切にdataclassのオブジェクトに変換できません(pydanticではできます)。
  • pydanticでは、型ヒントを使ってバリデーションを行います。
  • pydanticを使うには、インストールが必要です。

PyQでは下記からdataclassesモジュールのdataclassについて学べます。dataclassについて興味を持ちましたら確認してみてください。

Copyright ©2017- BeProud Inc. All rights reserved.