dataclass
このレッスンでは、@dataclass を使って、データを入れるだけのクラスを短く書けるようになります。
__init__ の書き写しが退屈になる
属性が増えるほど __init__ は同じ言葉の繰り返しになります。
class Expense:
def __init__(self, name, price, category):
self.name = name
self.price = price
self.category = category3つの属性に対して、引数と代入で名前を6回書いています。書き写しの途中で1つ抜けても文法エラーにはならないので、見つけにくいバグの種になります。
@dataclass は __init__ を自動で作る
標準ライブラリの dataclasses から dataclass を読み込み、クラスの上に @dataclass と付けます。すると、クラスの直下に並べた変数から __init__ が自動的に作られます。
from dataclasses import dataclass
@dataclass
class Expense:
name: str
price: int
category: str = "未分類"
milk = Expense("牛乳", 158, "食費")
print(milk.price) # 158name: str の : str は型ヒントで、「ここには文字列が入る想定だ」と読む人に伝える印です。dataclass はこの並びを見てフィールドを決めるので、型ヒントは省略できません。= "未分類" のように既定値も書けます。既定値のあるフィールドは、無いフィールドより後ろに置く決まりです。
比較と表示も付いてくる
@dataclass は __init__ だけでなく __repr__ と __eq__ も自動で作ります。print したときに中身が見える形になり、== で「全フィールドが同じなら等しい」と判定できるようになります。前のレッスンで手書きした __str__ の仕事を、かなりの部分まで肩代わりしてくれます。
メソッドは今までどおり書ける
自動で作られるのは決まりきった部分だけです。total や label のような自分のメソッドは、これまでと同じく def で書き足せます。デコレータの @ は、そのすぐ下のクラスや関数に機能を足す記法です。
要件
- クラスに @dataclass を付けること
- name, price, category を型ヒント付きで並べ、category の既定値を「未分類」にすること
- label は「牛乳(食費) 158円」の形の文字列を返すこと
- expense_labels は label の結果を並べたリストを返すこと
入出力例
expense_labels([["牛乳",158,"食費"],["電車代",420,"交通費"]]) → ["牛乳(食費) 158円","電車代(交通費) 420円"]
expense_labels([["牛乳",158,"食費"],["謎の出費",300]]) → ["牛乳(食費) 158円","謎の出費(未分類) 300円"]ヒント
編集 LuaGate編集部