演算子オーバーロードの基本概念
単項演算子のオーバーロード
単項演算子では、オブジェクトに対する正符号(+)と負符号(-)の動作を定義します。
import math
from array import array
class Vector:
def __init__(self, elements):
self._elements = array('d', elements)
def __neg__(self):
"""負符号(-)演算子のオーバーロード"""
return Vector(-x for x in self._elements)
def __pos__(self):
"""正符号(+)演算子のオーバーロード"""
return Vector(self._elements)
def __iter__(self):
return iter(self._elements)
def __str__(self):
return str(tuple(self._elements))
# 単項演算子のテスト
vector = Vector([3, 4, 5])
print(-vector) # (-3.0, -4.0, -5.0)
print(+vector) # (3.0, 4.0, 5.0)
加算演算子のオーバーロード
ベクトル同士の加算を実装するには、__add__メソッドを定義します。
class Vector:
def __init__(self, elements):
self._elements = array('d', elements)
def __add__(self, other):
"""加算演算子(+)のオーバーロード"""
if len(self._elements) != len(other._elements):
raise ValueError("ベクトルの次元が一致しません")
return Vector(a + b for a, b in zip(self._elements, other._elements))
def __radd__(self, other):
"""右側加算の実装"""
return self.__add__(other)
def __iter__(self):
return iter(self._elements)
def __str__(self):
return str(tuple(self._elements))
# 加算演算子のテスト
v1 = Vector([1, 2, 3])
v2 = Vector([4, 5, 6])
result = v1 + v2
print(result) # (5.0, 7.0, 9.0)
比較演算子のオーバーロード
等価比較演算子を実装する例を示します。
class Vector:
def __init__(self, elements):
self._elements = array('d', elements)
def __eq__(self, other):
"""等価比較演算子(==)のオーバーロード"""
if len(self._elements) != len(other._elements):
return False
return all(a == b for a, b in zip(self._elements, other._elements))
def __iter__(self):
return iter(self._elements)
def __len__(self):
return len(self._elements)
# 比較演算子のテスト
v1 = Vector([1, 2, 3])
v2 = Vector([1, 2, 3])
v3 = Vector([4, 5, 6])
print(v1 == v2) # True
print(v1 == v3) # False
拡張代入演算子のオーバーロード
拡張代入演算子+=を実装するには、__iadd__メソッドを定義します。
class Vector:
def __init__(self, elements):
self._elements = array('d', elements)
def __iadd__(self, other):
"""拡張加算代入演算子(+=)のオーバーロード"""
if len(self._elements) != len(other._elements):
raise ValueError("ベクトルの次元が一致しません")
for i in range(len(self._elements)):
self._elements[i] += other._elements[i]
return self
def __iter__(self):
return iter(self._elements)
def __str__(self):
return str(tuple(self._elements))
# 拡張代入演算子のテスト
v1 = Vector([1, 2, 3])
v2 = Vector([4, 5, 6])
v1 += v2
print(v1) # (5.0, 7.0, 9.0)
演算子オーバーロードの実装ポイント
- 単項演算子は__neg__と__pos__で実装
- 二項演算子は__add__、__sub__などで実装
- 比較演算子は__eq__、__lt__などで実装
- 拡張代入演算子は__iadd__、__isub__などで実装
- 演算子の優先順位はPythonの組み込みルールに従う