Pythonデータクラスの基本的な使い方:初期化されていない変数はインスタンス変数、初期化された変数はクラス変数のようにふるまう
2022.11.27
Python のデータクラスは次のように宣言します。
from dataclasses import dataclass
@dataclass
class Post:
id: int
title: str
description: str
date_created: int
p = Post(6, 'Python入門', 'Pythonを解説します', 1575424482)
print(type(p)) # <class '__main__.Post'>
print(p.id) # 6
print(p.title) # Python入門
print(p.description) # Pythonを解説します
print(p.date_created) # 1575424482
まず dataclasses から dataclass をインポートし、クラス宣言の前に dataclass デコレーターをつけます。id などの変数は型も用意します。通常、これらの変数は def __init__(self):
に入れますが、データクラスではそうした書き方はしません。
Python データクラスの変数を初期化する
変数は初期化できます。
from dataclasses import dataclass
@dataclass
class Post:
id: int = 1
title: str = ''
description: str = ''
date_created: int = 0
p = Post()
p.id = 6
p.title = 'Python入門'
p.description = 'Pythonを解説します'
p.date_created = 1575424482
初期化すると Post(6, '入門', '解説', 157)
という宣言はできなくなります。
Python データクラスのクラス変数とインスタンス変数
データクラスの変数は 2 つあります。
- 初期化されていない変数
- 初期化された変数
初期化されていない変数はインスタンス変数のようにふるまいます。
from dataclasses import dataclass
@dataclass
class Post:
id: int
title: str
description: str
date_created: int
p = Post(id=6, title='a', description='b', date_created=10)
print(p.id) # 6
print(Post.id) # AttributeError: type object 'Post' has no attribute 'id'
データクラスの初期化されていない変数は、インスタンスからアクセスできますが、クラスからはアクセスできません。Post.id はエラーです。
初期化された変数はクラス変数のようにふるまいます。
from dataclasses import dataclass
@dataclass
class Post:
id: int = 6
title: str = 'a'
description: str = 'b'
date_created: int = 10
p = Post()
print(p.id) # 6
print(Post.id) # 6
データクラスの初期化された変数は、インスタンス・クラスの両方からアクセスできます。
Python データクラスの変数はすべて初期化するか、またはすべて初期化しない
データクラスの変数は「すべてを初期化する」または「すべてを初期化しない」のどちらかです。下のコードはエラーです。
from dataclasses import dataclass
@dataclass
class Post:
id: int = 6
title: str = 'a'
description: str
date_created: int
# TypeError: non-default argument 'description' follows default argument
初期化された変数と初期化されていない変数が混ざっているとエラーになります。
インスタンスを辞書に書きだす
import dataclasses
from dataclasses import dataclass
@dataclass
class Post:
id: int = 1
title: str = ''
description: str = ''
date_created: int = 0
p = Post()
p.id = 6
p.title = 'Python入門'
p.description = 'Pythonを解説します'
p.date_created = 1575424482
d = dataclasses.asdict(p)
print(d)
# {'id': 6, 'title': 'Python入門', 'description': 'Pythonを解説します', 'date_created': 1575424482}
インスタンスを辞書に出力するには dataclasses をインポートし、dataclasses の asdict を使います。出力される辞書はインスタンスの各変数です。