Python で dataclass を使ってクラスが保持するデータを簡単に定義する
Python 3.7 からクラスで保持させるデータを簡単に定義出来る dataclasses がサポートされました。 今回は「dataclass を使った場合」「使わない場合」の書き方を比較してみます。
dataclass を使わない書き方
dataclass を使わない場合、__init__() の引数に「クラスで保持させたいデータ」を渡す必要があります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13  | #!/usr/bin/env python3
class Person:
    def __init__(self, name, height, weight):
        self.name = name
        self.height = height
        self.weight = weight
    def greet(self):
        print(f"Hello, {self.name}!")
person1 = Person("John", 180, 90)
person1.greet()
  | 
 
このコードの実行例は以下の通りです。
dir() で person1 を表示すると以下のようになりました。
 | ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'greet', 'height', 'name', 'weight']
  | 
 
dataclass を使った書き方
dataclass を使った書き方は以下の通りです。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16  | #!/usr/bin/env python3
from dataclasses import dataclass
@dataclass
class Person:
    name: str
    height: int
    weight: int
    def greet(self):
        print(f"Hello, {self.name}!")
person1 = Person("John", 180, 90)
person1.greet()
  | 
 
実行例は以下の通りです。 書き方は異なるものの、本質的な動作は変わりません。
同じく dir で person1 を確認すると以下のように表示されました。 「dataclass を利用していない場合」と比較すると暗黙的に特殊メソッドが作成されていることが分かります。
 | ['__annotations__', '__class__', '__dataclass_fields__', '__dataclass_params__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'greet', 'height', 'name', 'weight']
  |