マジックメソッド(またはダンダーメソッド – ダブルアンダースコアから)は、名前が二つのアンダースコアで始まり、二つのアンダースコアで終わる特別なメソッドです。例えば、__init__、__str__、__add__などです。これらは、独自のクラスのインスタンスをPythonの構文と動作に組み込むことを可能にします:算術演算、比較、文字列への変換、コレクションプロトコルとの動作などに対する反応を定義します。
例:
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 __str__(self): return f"Vector({self.x}, {self.y})" v1 = Vector(1, 2) v2 = Vector(3, 4) print(v1 + v2) # v1.__add__(v2)を呼び出し、Vector(4, 6)を返す
自分のクラスに
__eq__を実装しなかった場合、演算子==でそのインスタンス同士はどのように比較されますか?
回答: デフォルトでは、演算子==はオブジェクトを同一性(メモリアドレス、演算子isに類似)で比較します。マジックメソッド__eq__をオーバーライドしない限り。
class A: pass print(A() == A()) # False、オブジェクトは「同じように見える」が
物語
グラフの構造を比較する必要のあるプロジェクトで、__eq__メソッドを実装しませんでした。そのため、「ノードがすでに追加されているか」を確認する際に不正確な結果が得られました。なぜなら、演算子==がオブジェクトをidで比較していたからで、内容ではなかったのです。
物語
REST APIを作成中に、ログのためにオブジェクトを文字列にシリアル化する際にstr(obj)を使用しましたが、__str__を定義するのを忘れてしまいました。その結果、<MyObj object at 0x...>という読みづらいテキストが出力され、問題の診断が難しくなりました。
物語
数学的計算のためのライブラリでは、__add__のみを実装し、演算子+=のための__iadd__を忘れてしまいました。その結果、v += wという式は期待通りに動作せず(新しいオブジェクトが作成され、古いものは更新されなかった)、複雑な計算においてメモリリークが発生しました。