Skip to content

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()

このコードの実行例は以下の通りです。

1
Hello, John!

dir()person1 を表示すると以下のようになりました。

1
['__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()

実行例は以下の通りです。 書き方は異なるものの、本質的な動作は変わりません。

1
Hello, John!

同じく dirperson1 を確認すると以下のように表示されました。 「dataclass を利用していない場合」と比較すると暗黙的に特殊メソッドが作成されていることが分かります。

1
['__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']