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__:==演算子の定義。
これらを適切に実装することで、使いやすく直感的なクラスを設計することができます。
