1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python Dataclass解説:基礎から実践まで

Posted at

初めに

Python3.7で導入されたdataclassデコレータは、データクラスを作成するための方法を提供します。この記事では、dataclassの核となる機能と実践的な使用例を詳しく解説し、プロジェクトでの効果的な活用方法を紹介します。

使用上のおすすめ事項

  1. データの保存が主な目的のクラスを作成する場合は、dataclassの使用を検討する
  2. 変更不可能なデータにはfrozen=Trueを使用する
  3. 初期化後の検証が必要な場合は__post_init__を使用する

Dataclassとは

__init__(), __repr()__, __eq()__などの特殊メソッドを自動的にクラスに追加するpythonのデコレータです。従来の方法と比較して、理解を深めましょう:

# 従来のクラス定義方法
class TraditionalStudent:
    def __init__(self, name: str, age: int, grade: int):
        self.name = name
        self.age = age
        self.grade = grade
    
    def __repr__(self):
        return f"Student(name='{self.name}', age={self.age}, grade={self.grade})"
    
    def __eq__(self, other):
        return (self.name == other.name and 
                self.age == other.age and 
                self.grade == other.grade)

# dataclassを使用した方法
from dataclasses import dataclass

@dataclass
class Student:
    name: str
    age: int
    grade: int

ご覧の通り、dataclassを使用したバージョンはより良く簡潔でありながら、同じ機能を提供しています。

dataclass登場以前:namedtupleの試み

まず、dataclassが登場する前のpythonにおけるデータクラスの扱い方を見てみましょう:

from collections import namedtuple

# namedtuple の使用
Person = namedtuple('Person', ['name', 'age', 'city'])

# インスタンスの作成
person = Person('田中', 30, '東京')
print(person.name)  # 属性としてアクセス
print(person[0])    # タプルとしてもアクセス可能

namedtupleの制限事項:

  1. 作成後は変更不可
  2. type-hintがない
  3. デフォルト値をサポートしていない
  4. メソッドの追加が困難

これらの制限が、dataclass誕生の背景となりました。

dataclassの主要機能

デフォルト値の設定

dataclassはフィールドのデフォルト値を設定するための方法を提供します:

from dataclasses import dataclass, field
from datetime import datetime
from typing import List

@dataclass
class User:
    # 基本型のデフォルト値
    name: str
    age: int = 18
    active: bool = True
    
    # 可変型のデフォルト値
    scores: List[int] = field(default_factory=list)
    

オブジェクトの順序付け

order=Trueパラメータを使用して、順序付けを有効にできます:

@dataclass(order=True)
class Student:
    grade: int
    name: str
    age: int

    def __post_init__(self):
        # カスタムソートロジック
        self.__dict__['_sort_index'] = (self.grade, self.name)

# 使用例
students = [
    Student(grade=3, name="Alice", age=20),
    Student(grade=2, name="Bob", age=19),
    Student(grade=3, name="Charlie", age=21)
]
sorted_students = sorted(students)  # grade と name でソート

イミュータブルデータ

frozen=Trueパラメータを使用して、変更不可能なデータクラスを作成できます:

@dataclass(frozen=True)
class Configuration:
    host: str
    port: int
    database: str
    
    @property
    def connection_string(self) -> str:
        return f"{self.host}:{self.port}/{self.database}"
    
    def with_new_port(self, new_port: int) -> 'Configuration':
        return Configuration(
            host=self.host,
            port=new_port,
            database=self.database
        )

実践的な使用例

from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Optional

@dataclass(frozen=True)
class Address:
    street: str
    city: str
    country: str
    postal_code: str

@dataclass(order=True)
class Person:
    name: str
    age: int
    addresses: List[Address] = field(default_factory=list)
    created_at: datetime = field(default_factory=datetime.now)
    
    def __post_init__(self):
        self.__dict__['_sort_index'] = (self.name, self.age)

@dataclass(order=True)
class Employee(Person):
    employee_id: str
    department: str
    salary: float
    manager: Optional['Employee'] = None
    
    def __post_init__(self):
        super().__post_init__()
        if self.salary < 0:
            raise ValueError("Salary cannot be negative")
        self.__dict__['_sort_index'] = (self.department, self.name)

まとめ

Dataclassは、Pythonにおけるデータクラス処理の強力なツールです。ボイラープレートコードを削減するだけでなく、豊富な機能のサポートも提供します。この記事を通じて、dataclassの主要機能と実践的な使用方法を理解していただけたと思います。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?