この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
from dataclasses import dataclass
@dataclass
class Person: # クラスのフィールド(属性)は型アノテーションを用いて指定
name: str
height: float
weight: float
def hello(self):
print(f'hello {self.name}') # メソッドも定義できる
p = Person('kawasaki', 180, 72)
p.hello() # hello kawasaki
# 文字列化
repr(p) # "Person(name='kawasaki', height=180, weight=72)"
# 同値性の比較
p2 = Person('isshiki', 190, 78)
print(p == p2) # False
@dataclass
class Person: # フィールドにはデフォルト値を指定可能
name: str
height: float = 0
weight: float = 0
def hello(self):
print(f'hello {self.name}')
p = Person('kawasaki')
print(p.height) # 0
# 生成する特殊メソッドのカスタマイズ
@dataclass(init=False)
class Person:
name: str
height: float
weight: float
def __init__(self, name='nanashi', height=170, weight=60):
self.name = name
self.height = height
self.weight = weight
def hello(self):
print(f'hello {self.name}') # メソッドも定義できる
p = Person(init=False)
print(p) # Person(name='nanashi', height=170, weight=60)
@dataclass(order=True) # インスタンス同士の大小比較を行えるようにする
class Person: # クラスのフィールド(属性)は型アノテーションを用いて指定
name: str
height: float = 0
weight: float = 0
def hello(self):
print(f'hello {self.name}') # メソッドも定義できる
p0 = Person('kawasaki', 180, 70)
p1 = Person('kawasaki', 178, 72)
if p0 > p1:
print('p0 is greater than p1')
else:
print('p0 is lesser than or equal to p1')
# 出力結果:
#
パラメーター | 説明 |
---|---|
init | __init__メソッドを生成するかどうか。デフォルト値はTrue(生成する) |
repr | __repr__メソッドを生成するかどうか。デフォルト値はTrue(生成する) |
eq | __eq__メソッドを生成するかどうか。デフォルト値はTrue(生成する) |
order | __lt__/__le__/__gt__/__ge__メソッドを生成するかどうか。デフォルト値はFalse(生成しない) |
unsafe_hash | __hash__メソッドを生成するかどうか。デフォルト値はFalse(eqパラメーターとfrozenパラメーターがTrueの場合は__hash__メソッドを生成するが、それ以外のときは生成しない)。Trueなら(仮にそのクラスのインスタンスがイミュータブルでなくとも)__hash__メソッドを生成する |
frozen | このクラスのインスタンスのフィールド(属性)への代入を許すかどうか。デフォルト値はFalse(代入を許す) |
match_args | __match_args__属性を作成するかどうか。デフォルト値はTrue(作成する) |
kw_only | 全てのフィールドをキーワード専用とするかどうか。デフォルト値はFalse(キーワード専用としない) |
slots | __slots__属性を作成するかどうか。デフォルト値はFalse(作成しない) |
weakref_slots | __weakref__属性を作成するかどうか。デフォルト値はFalse(作成しない) |
dataclassデコレーターのパラメーター |
Pythonに標準で添付されるdataclassesモジュールを使うと、クラス定義において自動的に特殊メソッド(__init__メソッド、__repr__メソッドなど)を生成したり、その属性(これをデータクラスについては「フィールド」と呼ぶ)のデフォルト値を可変なものにしたりするためのデコレーターや関数を使用できるようになる。
dataclassesモジュールにはdataclassデコレーターがあり、これを使うことでクラスの定義を簡単に行える。以下に例を示す。
from dataclasses import dataclass
@dataclass
class Person: # クラスのフィールド(属性)は型アノテーションを用いて指定
name: str
height: float
weight: float
def hello(self):
print(f'hello {self.name}') # メソッドも定義できる
データクラスを定義するには「from dataclasses import dataclass」としてdataclassデコレーターをインポートして、これをクラス定義の前に置く(上記コード例の強調書体部分)。
このクラスのインスタンスが持つフィールド(属性)については型アノテーションを使って指定する。上のコード例ではnameフィールドには文字列を、heightフィールドとweightフィールドには浮動小数点数を指定している。ただし、インスタンス生成時にこれをチェックするわけではない点には注意しよう。
また、helloメソッドのように通常のメソッドを定義することも可能だ(「データクラス」という名前からはデータを保存するだけで、何かの操作を定義できないように思う人もいるかもしれないがこのデコレーターにより作成されるのは通常のクラスである)。
インスタンスの生成は通常のクラスと同様だ。
p = Person('kawasaki', 180, 72)
p.hello() # hello kawasaki
デコレーターに引数を渡さない場合にはデフォルトで以下の特殊メソッドと属性が追加される。
そのため、インスタンスの初期化、repr関数(およびこれを使うstr関数)による文字列化、同値性の比較というクラス定義における基本処理の記述を省略できる。
# 文字列化
repr(p) # "Person(name='kawasaki', height=180, weight=72)"
# 同値性の比較
p2 = Person('isshiki', 190, 78)
print(p1 == p2) # False
__repr__メソッドでは上の出力結果のようにインスタンス生成に役立つ形式で文字列化が行われる。もっとシンプルな結果が必要なら、自分で__str__メソッドを定義するようにしよう。
データクラスのインスタンスのフィールドにデフォルト値を持たせるには次のように型アノテーションでデフォルト値を指定するだけでよい。
@dataclass
class Person: # フィールドにはデフォルト値を指定可能
name: str
height: float = 0
weight: float = 0
def hello(self):
print(f'hello {self.name}')
Copyright© Digital Advantage Corp. All Rights Reserved.