クラスを作るたびに __init__ で self.xxx = xxx を何行も書くのは、正直ちょっと面倒ですよね。そんなときに使えるのが、Python 3.7 から標準で使える dataclass です。
この記事では、dataclass の基本、デフォルト値、リストを持たせるときの注意点、不変にする frozen までを、実行結果つきで初心者向けに解説します。クラスの基本を押さえている前提で進めますので、不安な方は先にPythonのクラスの基本を読んでみてください。
dataclassとは?
dataclass は、「データを持つことが主な目的のクラス」を、少ないコードで書くための仕組みです。デコレータ @dataclass を付けるだけで、__init__ や __repr__(表示用)などが自動で作られます。
通常のクラスとの比較
まずは通常のクラスで書いた場合です。
class Member:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Member(name={self.name!r}, age={self.age!r})"
m = Member("田中", 28)
print(m) # Member(name='田中', age=28)これを dataclass で書くと、次のようになります。
from dataclasses import dataclass
@dataclass
class Member:
name: str
age: int
m = Member("田中", 28)
print(m) # Member(name='田中', age=28)
print(m.name) # 田中
print(m == Member("田中", 28)) # True属性を「名前: 型」の形で並べるだけです。print したときの表示も分かりやすく、== による比較も属性の値で判定してくれます。型ヒントの書き方は型ヒントの記事で詳しく解説しています。
デフォルト値を指定する
from dataclasses import dataclass
@dataclass
class Member:
name: str
age: int = 20
city: str = "東京"
print(Member("佐藤"))
# Member(name='佐藤', age=20, city='東京')
print(Member("鈴木", 35, "大阪"))
# Member(name='鈴木', age=35, city='大阪')デフォルト値のある属性は、ない属性より後ろに書くのがルールです。
リストを持たせるときは field を使う
リストや辞書のような変更できる値を、そのままデフォルト値にするとエラーになります。複数のインスタンスで同じリストを共有してしまう事故を防ぐためです。そんなときは field(default_factory=…) を使います。
from dataclasses import dataclass, field
@dataclass
class Team:
name: str
members: list = field(default_factory=list)
a = Team("A班")
b = Team("B班")
a.members.append("田中")
print(a.members) # ['田中']
print(b.members) # []独学でここまで進めると「設計として正しいのか」を誰かに見てほしくなってくるはずです。学習環境を整える選択肢として、Pythonが学べるプログラミングスクールの比較記事も参考にしてみてください。
frozen=True で値を変更できなくする
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(1, 2)
print(p) # Point(x=1, y=2)
# p.x = 10 # FrozenInstanceError になりますfrozen=True にすると、作成後の属性の書き換えができなくなります。座標や設定値など、変わってほしくないデータに向いています。
辞書やタプルに変換する
from dataclasses import dataclass, asdict, astuple
@dataclass
class Member:
name: str
age: int
m = Member("田中", 28)
print(asdict(m)) # {'name': '田中', 'age': 28}
print(astuple(m)) # ('田中', 28)asdict を使うと、JSONへの出力などがしやすくなります。JSONの扱いはPythonのjsonモジュールの記事も参考になります。
もっと効率的にPythonを学びたい人へ
dataclass のような設計に関わる内容は、コードレビューを受けられる環境で学ぶと上達が早くなります。マンツーマンで見てもらいたい方は、スクールの無料カウンセリングを活用してみてください。
Winスクールの「Python Winner」は、マンツーマン指導で未経験からPythonを学べ、転職サポートや無料カウンセリングにも対応しています。まずは無料カウンセリングで、自分に合うか確かめてみてはいかがでしょうか。
※本記事には広告(アフィリエイトリンク)を含みます。
Pythonプログラミング|マンツーマンレッスンで初めてをプロに育てる【Python Winner】![]()
他のスクールとも比べたい方は、スクールの比較記事もあわせてご覧ください。資格取得を目指す方はPython3エンジニア認定基礎試験の参考書比較も参考になります。
まとめ
- @dataclass を付けると __init__ や __repr__ が自動生成される
- 属性は「名前: 型」の形で書き、デフォルト値は後ろに置く
- リストや辞書は field(default_factory=list) を使う
- frozen=True で書き換え不可にできる
- asdict・astuple で辞書やタプルに変換できる
まずは、これまで書いたクラスのうち「データを持つだけ」のものを dataclass に置き換えてみましょう。
ナノトイラボ 
