きれいに書く

INPUT · スライド

データだけのクラスを短く書く

01 / 07

あの写すだけの行

第5章でクラスを覚えたとき、__init__ の中にこう書いたのを覚えているかな。

class Kaiin:    def __init__(self, namae, toshi):        self.namae = namae        self.toshi = toshi

受け取った値を、そのまま属性に写しているだけの行だね。項目が5つあれば5行、10あれば10行。同じことを名前だけ変えてくり返しているのに、ずっと書き続けることになる。

02 / 07

@dataclass を1行足す

dataclasses という標準ライブラリから dataclass を取り出して、クラスのすぐ上の行に @dataclass と書く。@ で始まるこの書きかたをデコレーター(かざり)と呼ぶよ。

__init__ はもう書かない。かわりに持ちものを型ヒントつきで並べるだけ。前のレッスンでやった namae: str の形が、そのまま使えるんだ。

from dataclasses import dataclass@dataclassclass Kaiin:    namae: str    toshi: intkaiin = Kaiin("ゆい", 15)print(kaiin.namae)print(kaiin.toshi)

実行結果

ゆい
15

03 / 07

そのまま print できる

第5章では、__str__ を書かずにインスタンスを print すると、こんな文字が出たね。

<__main__.Kaiin object at 0x7f3a1c0d2e50>

うしろの番地は実行のたびに変わるので、あてにできなかった。@dataclass をつけたクラスは、それだけでクラス名と持ちものが並んだ、読める表示になるよ。

from dataclasses import dataclass@dataclassclass Kaiin:    namae: str    toshi: intprint(Kaiin("ゆい", 15))

実行結果

Kaiin(namae='ゆい', toshi=15)

04 / 07

== で中身を比べられる

もうひとつ勝手についてくるのが == での比較だよ。

ふつうのクラスだと、中身が同じでも別々に作った実物は等しくない。@dataclass をつけると、持ちものが全部同じなら等しいと見てくれる。「同じ会員かどうか」を、自分で1項目ずつ比べなくてよくなるんだ。

from dataclasses import dataclass@dataclassclass Kaiin:    namae: str    toshi: inta = Kaiin("ゆい", 15)b = Kaiin("ゆい", 15)print(a == b)

実行結果

True

05 / 07

初期値も書ける

型ヒントのうしろに = 値 を足すと、渡さなかったときの値になる。第3章でやった引数の初期値と、まったく同じ仕組みだよ。

初期値のある項目は、初期値の無い項目より後ろに並べること。逆にすると TypeError で怒られるよ。

from dataclasses import dataclass@dataclassclass Kaiin:    namae: str    nensuu: int = 1print(Kaiin("みなと"))print(Kaiin("ゆい", 3))

実行結果

Kaiin(namae='みなと', nensuu=1)
Kaiin(namae='ゆい', nensuu=3)

06 / 07

メソッドはこれまでどおり

@dataclass が省いてくれるのは、書かなくても分かるところだけだよ。self を使ったメソッドは、これまでどおりクラスの中に書ける。

つまり @dataclass はクラスの置きかえではなく、決まりきった行を消してくれる道具なんだ。

from dataclasses import dataclass@dataclassclass Kaiin:    namae: str    nensuu: int    def nenkaihi(self) -> int:        if self.nensuu >= 3:            return 4000        return 5000kaiin = Kaiin("ゆい", 3)print(kaiin.nenkaihi())

実行結果

4000

07 / 07

使いどころ

目安はかんたんだよ。データを持つのが主な役目のクラスなら @dataclass。処理のほうが主役なら、これまでどおり __init__ を書けばいい。

  • @dataclass … __init__ ・読める表示・== がついてくる
  • 持ちものは型ヒントつきで並べる
  • メソッドはふつうに書ける

書く行が減るぶん、そのクラスにしかない大事な処理が目立つようになる。これがこの章の最後の道具だよ。次のレッスンで、章の4つを組み合わせよう。