0
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の基本をやさしく解説

Posted at

Pythonの学習中に @dataclass という便利そうなものを見つけました。
ただ、最初は「どうして勝手に __init__() が作られるの?」「コンストラクター引数って何?」といった疑問がありました。
この記事は、自分の理解を整理するための学習記録です。

dataclassとは?

Python3.7から使える @dataclass は、クラスに自動的に初期化処理や表示処理を追加してくれる便利な機能です。
from dataclasses import dataclass を使って、クラス定義の上に @dataclass を書くことで有効になります。

通常、クラスを定義するときには __init__() を手動で書く必要があります。

class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age

user = User("Taro", 30)
print(user.name)  # Taro

これが @dataclass を使うと、次のようにすっきり書けます。

from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int

user = User("Taro", 30)
print(user.name)  # Taro

nameage をクラス定義の中に書くだけで、__init__() メソッドが自動生成され、初期化処理が自動で行われるのが大きな特徴です。

dataclassとコンストラクター引数

クラスを使ってインスタンスを作るときに渡す値(__init__() に渡される値)を「コンストラクター引数」と呼びます。

たとえば次のようにインスタンスを作るとき、

user = User("Hanako", 25)

この "Hanako"25 が、__init__() に渡される 引数 です。

@dataclass を使うと、自動的に下記のような __init__() が作られているイメージです。

def __init__(self, name: str, age: int):
    self.name = name
    self.age = age

つまり、dataclassで定義された変数(属性)は、そのままコンストラクター引数になります。

デフォルト値と引数の順番

dataclassでも、引数にデフォルト値を設定できます。

from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int = 20

user1 = User("Ken")
print(user1)  # User(name='Ken', age=20)

user2 = User("Ken", 35)
print(user2)  # User(name='Ken', age=35)

ただし注意点として、デフォルト値がある引数の後に、デフォルト値なしの引数を書くとエラーになります

# エラーになる例
@dataclass
class User:
    name: str = "Ken"
    age: int        # ❌ デフォルト値がない引数が後ろに来ている

# 正しい例
@dataclass
class User:
    name: str
    age: int = 20   # ✅ デフォルト値がある引数が後ろ

このように、dataclassの初期化も通常の関数定義と同じく、「位置引数 → キーワード引数」の順に並べる必要があるということを覚えておくと安心です。

field()を使ってコンストラクター引数を制御する

もっと細かく初期化の挙動を変えたいときには、field() を使います。
たとえば init=False を指定すれば、__init__() の引数に含めないようにできます。

from dataclasses import dataclass, field

@dataclass
class User:
    name: str
    age: int = 20
    id: int = field(init=False)

user = User("Miki")
user.id = 1001  # 後から代入する
print(user)     # User(name='Miki', age=20, id=1001)

このように field(init=False) を使うことで、「後からセットしたい値」「計算で自動設定される値」などに対応できます。

まとめ

  • dataclassを使うと、__init__() などを自動で作ってくれる
  • dataclassの属性はそのままコンストラクター引数になる
  • デフォルト値がある引数は、必ず後ろに書く必要がある
  • field(init=False) を使うと、その属性は __init__() に含まれない

次回は、asdict() を使ってdataclassを辞書に変換したり、JSONに変換する方法についてまとめる予定です。

0
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
0
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?