Pythonの特殊メソッド(マジックメソッド)入門:initやstrでクラスをカスタマイズする

Pythonでクラスを定義する際、アンダースコア2つで囲まれたメソッド(例: __init__)を見かけることがよくあります。これらは特殊メソッド(Special Methods)、あるいはマジックメソッドと呼ばれます。

特殊メソッドを定義することで、自作のクラスに対して、Pythonの組み込み型(リストや数値など)と同じような振る舞いを持たせることができます。例えば、オブジェクト同士を + で足し算したり、print() で表示したりする動作をカスタマイズできます。

この記事では、代表的な特殊メソッドの役割と実装方法について解説します。

目次

特殊メソッドとは

特殊メソッドは、__メソッド名__ という命名規則を持つメソッドです。これらはプログラマが直接呼び出す(obj.__str__())ことはあまりなく、特定の構文や組み込み関数が実行されたときに、Pythonの内部から自動的に呼び出されます

構文 / 関数呼び出される特殊メソッド
インスタンス生成__init__
print(obj) / str(obj)__str__
repr(obj)__repr__
obj1 + obj2__add__
obj1 == obj2__eq__

基本的な特殊メソッド

まずは、クラス定義においてほぼ必須となる基本的なメソッドを紹介します。例として、2次元座標を表す Coordinate クラスを作成します。

1. 初期化: __init__

インスタンスが生成される際に呼び出され、属性の初期設定を行います(コンストラクタ)。

2. 文字列化: __str____repr__

オブジェクトの文字列表現を定義します。

  • __str__: ユーザー向け。print() 関数などで使われます。
  • __repr__: 開発者向け。デバッグ時や、リストの中に格納されたときの表示に使われます。
class Coordinate:
    def __init__(self, x, y):
        """初期化メソッド"""
        self.x = x
        self.y = y

    def __str__(self):
        """print()などで呼ばれる文字列"""
        return f"座標({self.x}, {self.y})"

    def __repr__(self):
        """開発者向けの厳密な文字列"""
        return f"Coordinate({self.x}, {self.y})"

# インスタンス化 (__init__ が呼ばれる)
point = Coordinate(10, 20)

# 文字列化 (__str__ が呼ばれる)
print(f"出力: {point}")

# リスト内での表示 (__repr__ が呼ばれる)
points_list = [point, Coordinate(5, 5)]
print(f"リスト: {points_list}")

実行結果:

出力: 座標(10, 20)
リスト: [Coordinate(10, 20), Coordinate(5, 5)]

演算子のカスタマイズ(演算子オーバーロード)

特殊メソッドの真骨頂は、自作クラスに四則演算などの機能を付与できる点です。

3. 加算: __add__

+ 演算子が使用されたときの動作を定義します。ここでは、2つの座標を足し合わせる処理(ベクトルの加算)を実装します。

4. 等価判定: __eq__

== 演算子が使用されたときの動作を定義します。デフォルトでは「同じオブジェクト(メモリアドレス)か」を判定しますが、ここでは「xとyの値が同じなら等しい」とみなすように変更します。

class Coordinate:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return f"({self.x}, {self.y})"

    def __add__(self, other):
        """
        + 演算子の動作定義
        自分自身(self)と相手(other)のx, yを足した新しいインスタンスを返す
        """
        new_x = self.x + other.x
        new_y = self.y + other.y
        return Coordinate(new_x, new_y)

    def __eq__(self, other):
        """
        == 演算子の動作定義
        値が同じなら True を返す
        """
        return self.x == other.x and self.y == other.y

# 2つの座標を作成
p1 = Coordinate(10, 20)
p2 = Coordinate(30, 40)
p3 = Coordinate(10, 20)

# 足し算 (__add__ が呼ばれる)
p_sum = p1 + p2
print(f"足し算の結果: {p_sum}")

# 等価判定 (__eq__ が呼ばれる)
print(f"p1 == p2: {p1 == p2}")
print(f"p1 == p3: {p1 == p3}")

実行結果:

足し算の結果: (40, 60)
p1 == p2: False
p1 == p3: True

__add__ を定義したことで、p1 + p2 という直感的な記述が可能になりました。

まとめ

特殊メソッド(マジックメソッド)を定義することで、自作クラスをPythonの言語機能に統合できます。

  • __init__: 初期化処理。
  • __str__ / __repr__: 文字列表現。
  • __add__: + 演算子の定義。
  • __eq__: == 演算子の定義。

これらを適切に実装することで、使いやすく直感的なクラスを設計することができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次