Python -特殊メソッド-
Pythonには、クラスを強力かつ柔軟にするための「特殊メソッド」(マジックメソッドとも呼ばれます)が多数存在する。これらの特殊メソッドを使うことで、クラスに特定の振る舞いを持たせたり、組み込みの操作をカスタマイズしたりできる
1. 特殊メソッド (Magic Methods)
特殊メソッドは、ダンダーメソッドとも呼ばれ、名前の前後にダブルアンダースコアがついているメソッド。これらのメソッドは、Pythonの特定の動作をカスタマイズするために使用される
代表的な特殊メソッド
__init__: コンストラクタメソッド。オブジェクトが生成される際に呼び出され、インスタンス変数の初期化を行う
class MyClass:
def __init__(self, value):
self.value = value
__str__: オブジェクトの文字列表現を返すメソッド。print()やstr()関数で呼び出される
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return f"MyClass with value: {self.value}"
obj = MyClass(10)
print(obj)
# 出力: MyClass with value: 10
__repr__: オブジェクトの「公式」な文字列表現を返すメソッド。repr()関数やインタプリタでの表示に使われる
class MyClass:
def __repr__(self):
return f"MyClass({self.value})"
__len__: len()関数に対応し、オブジェクトの長さを返す
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = MyList([1, 2, 3])
print(len(my_list))
# 出力: 3
__getitem__: インデックスアクセスを可能にするメソッド。obj[key]で呼び出される
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3])
print(my_list[0])
# 出力: 1
__add__: +演算子をオーバーロードするためのメソッド
class MyNumber:
def __init__(self, value):
self.value = value
def __add__(self, other):
return MyNumber(self.value + other.value)
def __str__(self):
return str(self.value)
num1 = MyNumber(10)
num2 = MyNumber(20)
result = num1 + num2
print(result) # 出力: 30
2. クラスの応用
クラスの応用では、特殊メソッドを活用してカスタムデータ構造を作成したり、オブジェクトの動作を制御したりできる
カスタムデータ構造の作成
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def __len__(self):
return len(self.items)
def __str__(self):
return str(self.items)
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack) # 出力: [1, 2, 3]
stack.pop()
print(stack) # 出力: [1, 2]
print(len(stack)) # 出力: 2
解説: Stack クラスは、スタックデータ構造を表現している。push メソッドで要素を追加し、pop メソッドで要素を取り出す。__len__や__str__メソッドを追加することで、スタックの長さや内容を簡単に確認できるようにしている
イミュータブルクラスの作成
イミュータブル(不変)オブジェクトとは、一度作成されると、その内容が変更されないオブジェクトのこと
class ImmutablePoint:
def __init__(self, x, y):
self._x = x
self._y = y
@property
def x(self):
return self._x
@property
def y(self):
return self._y
def __repr__(self):
return f"ImmutablePoint({self._x}, {self._y})"
# 作成後は属性を変更できない
point = ImmutablePoint(10, 20)
print(point) # 出力: ImmutablePoint(10, 20)
解説: ImmutablePoint クラスでは、@property デコレータを使って属性を読み取り専用にしている。これにより、オブジェクトの内容を変更することなく、安全に使用することができる
演算子オーバーロードを活用した複雑なオブジェクト操作
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
print(v1 + v2) # 出力: Vector(6, 8)
print(v1 - v2) # 出力: Vector(-2, -2)
解説: Vector クラスでは、__add__ および __sub__ メソッドを使ってベクトルの加算と減算をサポートしている。これにより、ベクトル同士の演算が直感的に行えるようになる