環境設定 数値 文字列 正規表現 リスト タプル 集合 辞書 ループ 関数 クラス データクラス 時間 パス ファイル スクレイピング その他

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 を使います。出力される辞書はインスタンスの各変数です。