🐍

Pythonのdataclassを知る

2022/12/27に公開

dataclassがよく分からなかった

たまに、dataclassを使っているコードを見かけて、今までよくわからずあまり気にせず雰囲気でよんでいたのですが、知らないと困ることがでてきたので少し調べてみました。

公式情報としては、PEP-557にかかれています。

https://peps.python.org/pep-0557/

読んでもよく使いどころが分かりませんね。というわけで、疑問点を1つ1つ確認していきます。

dataclassはデコレータをつかう必要がある

そもそもデコレータがあんまり分かってなかったり…以下がわかりやすかったです。

https://qiita.com/mtb_beta/items/d257519b018b8cd0cc2e

デコレータは、関数、クラスの前に@xxxxと書くことで使えるようになります。デコレータは、修飾という意味ですが、Pythonでは関数やクラスに特定の処理を追加することができるようです。ラッパー的なやつですね。

dataclassを使うときは@dataclassとデコレータとして使うわけですが、じゃあdataclassの実態はどんなコードなのかというと、以下にあります。

https://github.com/python/cpython/blob/29f98b46b77ee528477b9a7b335974b9682f7f14/Lib/dataclasses.py#L1209

はい、コード読んでも全然ピンときませんね。

dataclass使い方

実際に使ってみて、身体で覚えてみることにしましょう。

例えば以下みたいなKaraageクラスがあったとします(謎の例)

class Karaage():
    def __init__(self):
        self.name = 'karaage'
        self.option = []

データクラスを使って書くと以下のようにかけます。

from dataclasses import dataclass, field

@dataclass
class Karaage():
    name: str = 'karaage'
    option: list = field(default_factory=list)

dataclassを使うと便利な点

ポイント

  • 初期化が楽(def __init__(self)とか書かなくてよい)
  • 型アノテーションしやすい
  • dictとかjsonに変換しやすい(参照: Python3.7で導入されたdataclass入門
  • エディタの補完が使いやすくなる

中身を確認しやすい

インスタンスを確認するとき、普通にクラスで書くと以下のようにオブジェクトであることとアドレスが表示されます。

>>> karaage = Karaage()
>>> print(karaage)
<__main__.Karaage object at 0x1031c3cd0>

これが、データクラスを使って書くと、以下のように中身を表示してくれてちょっと見やすいです。

>>> karaage = Karaage()
>>> print(karaage)
Karaage(name='karaage', option=[])

一括でイミュータブルにできる

できるらしいです。

@dataclass(frozen=True)
class Karaage():
    name: str = 'karaage'
    option: list = field(default_factory=list)

dataclass使いどころ

データの格納がメインのクラスに使うというのが、基本的な使い方みたいです。

とりあえず全部クラスはdataclassにしてしまえばよいのでは?という考え方もありそうですが、あまり一般的ではないようです。

Twitterでのコメント

https://twitter.com/takaneh/status/1607507730063036417

まとめ

dataclassを調べてみました。

ものすごい便利とは個人的には感じませんでしたし、無理して使うことはないような印象を受けましたが、使っているコードたまにみかけるので、知っておいたほうが良いですね。

いくつか例をみると、さらに便利さに気づくかもしれません。そしたらこの記事に追記したいと思います。

参考

公式

https://peps.python.org/pep-0557/

https://docs.python.org/ja/3/library/dataclasses.html

https://github.com/python/cpython/blob/29f98b46b77ee528477b9a7b335974b9682f7f14/Lib/dataclasses.py#L1209

解説記事

https://myenigma.hatenablog.com/entry/2020/03/07/171015

https://qiita.com/ttyszk/items/01934dc42cbd4f6665d2

https://zenn.dev/enven/articles/8b80ff38461b4ff329aa

https://zenn.dev/kumamoto/articles/d0fb1208c47365

https://qiita.com/tag1216/items/13b032348c893667862a

参考リンク

https://yiskw713.hatenablog.com/entry/2023/05/05/182048

https://zenn.dev/ohke/articles/4a65d4b78637bc

関連記事

https://karaage.hatenadiary.jp/entry/2020/01/04/154338

Discussion