🐍

Pythonのクラス定義における主要な特殊メソッド

2025/01/06に公開

本記事の概要

本記事では、Pythonのクラス定義における主要な特殊メソッドについて解説します。
取り扱う特殊メソッドは以下の6つです:

  • __init__
  • __call__
  • __repr__
  • __eq__
  • __getitem__
  • __len__

また、ビルトイン関数であるsuper()と特殊メソッド__init__を組み合わせたsuper().__init__()についても簡単に解説します。

1. init, call, repr, eq

__init__, __call__, __repr__, __eq__ について解説します。

メソッド 説明
__init__ インスタンス生成時に呼び出されるコンストラクタです。主にパラメータの初期化や前処理に用います。
__call__ インスタンスを関数のように呼び出せるようにします。
__repr__ インタラクティブシェルやログ出力時などに使われる「オブジェクトの文字列表現」を返します。デバッグなどでそのときの状態を把握しやすくする目的で使用されることがあります。
__eq__ ==演算子による比較の挙動を定義します。2つのインスタンスが「同じ」であるかどうかの基準を任意に決めることができます。

実装例

class SimpleModel:
    # インスタンス生成時にパラメータを初期化
    def __init__(self, weights, bias):
        self.weights = weights
        self.bias = bias

    # モデルインスタンスを関数のように呼び出す
    def __call__(self, x):
        return self.weights * x + self.bias

    # オブジェクトの文字列表現を返す
    def __repr__(self):
        return f"SimpleModel(weights={self.weights}, bias={self.bias})"

    # モデル同士を比較し、重みとバイアスが同じなら同一とみなす
    def __eq__(self, other):
        return (self.weights == other.weights) and (self.bias == other.bias)

# モデル1を作成
model1 = SimpleModel(weights=2.0, bias=1.0)

# モデル2を作成
model2 = SimpleModel(weights=2.0, bias=1.0)

# モデル3を作成
model3 = SimpleModel(weights=3.0, bias=1.0)

# モデルを呼び出して`__call__`で定義した処理を実行
call_result = model1(5.0)
print("__call__の実行結果:", call_result)

# `__repr__`の出力確認
print("__repr__の出力結果:", model1)

# __eq__ による比較結果の出力
print("model1とmodel2の比較結果:", model1 == model2)
print("model1とmodel3の比較結果:", model1 == model3)

__call__の実行結果: 11.0
__repr__の出力結果: SimpleModel(weights=2.0, bias=1.0)
model1とmodel2の比較結果: True
model1とmodel3の比較結果: False

2. getitem, len

__getitem__, __len__ について解説します。

メソッド 説明
__getitem__ オブジェクトのインデックス参照などリストや辞書のようなアクセスを可能にします。
__len__ 要素数を返せるようにします。

実装例

class SimpleDataset:
    # dataとlabelsを受け取る
    def __init__(self, data, labels):
        self.data = data
        self.labels = labels

    # インデックス指定で要素を取り出す
    def __getitem__(self, index):
        return self.data[index], self.labels[index]

    # データ数を返す
    def __len__(self):
        return len(self.data)

# ダミーデータを用意
data = [0.1, 0.2, 0.3, 0.4]
labels = [0, 0, 1, 1]

# データセットを作成
dataset = SimpleDataset(data, labels)

# データ数を確認
print("データ数:", len(dataset))

# インデックス指定で要素を取り出す
initial_data, initial_label = dataset[0]
print("先頭の要素:", initial_data, initial_label)

# データセットをループで回す
for i in range(len(dataset)):
    data_item, label_item = dataset[i]
    print(f"Index: {i}, Data: {data_item}, Label: {label_item}")

データ数: 4
先頭の要素: 0.1 0
Index: 0, Data: 0.1, Label: 0
Index: 1, Data: 0.2, Label: 0
Index: 2, Data: 0.3, Label: 1
Index: 3, Data: 0.4, Label: 1

3. super().__init__()

Pythonのクラス定義においてsuper().__init__()は、主に以下のような役割を持っています:

  • 親クラスの初期化メソッド(__init__) を明示的に呼び出す
  • 複数のクラスを継承(多重継承)している場合でも、正しい継承順序で初期化処理を呼び出す
  • 親クラスの初期化時に設定されたインスタンス変数や処理を引き継ぐ

実装例

# 親クラスを定義
class ParentClass:
    def __init__(self, value):
        # valueを初期化する
        self.value = value

# 子クラスを定義
class ChildClass(ParentClass):
    def __init__(self, value, child_value):
        # 親クラスの__init__を呼び出し、親側の処理を引き継ぐ
        super().__init__(value)
        # 子クラス独自の属性を追加する
        self.child_value = child_value

上の例では、まずsuper().__init__(value)で親クラスのコンストラクタを呼び出し、valueを設定しています。その後、子クラス独自の属性としてchild_valueを設定しています。

定義したクラスを使用してみます:

# ChildClassのインスタンスを作成
child = ChildClass("ParentValue", "ChildValue")

# valueとchild_valueを出力
print(child.value)
print(child.child_value)

ParentValue
ChildValue

親クラスから引き継いだ処理と子クラス独自の属性を設定・出力できていることが確認できました。

まとめ

本記事では、Pythonのクラス定義における6つの主要な特殊メソッドについて解説しました。これらのメソッドを実装することで、以下のような機能をクラスに追加できます。

  • __init__: インスタンスの初期化処理を定義
  • __call__: インスタンスを関数のように呼び出す機能を実装
  • __repr__: デバッグに役立つオブジェクトの文字列表現を出力
  • __eq__: インスタンス同士の比較基準を定義
  • __getitem__: インデックスによる要素アクセスを実装
  • __len__: オブジェクトの長さや要素数を定義

Discussion