【Python】クラスで等価演算子(==)を使う方法:__eq__のオーバーライド解説
はじめに
Pythonで独自に定義したクラスのインスタンス同士を == 演算子で比較すると、意図した結果にならないことがあります。本記事では、その原因と、__eq__ メソッドをオーバーライドして正しく等価比較を行う方法を解説します。
デフォルトの挙動:なぜ False が返るのか
以下のコードのように、同じ値を持つ2つのインスタンスを等価演算子で比較すると、出力は False になります。
class Integer:
def __init__(self, number):
self.number = number
n1 = Integer(1)
n2 = Integer(1)
print bool(n1 == n2)
出力:
False
これは、Pythonがデフォルトではオブジェクトの識別子(ID)に基づいて比較を行うためです。つまり、値が同じでも別々に生成されたインスタンスは「異なるオブジェクト」とみなされます。
__eq__ をオーバーライドして解決する
この問題を解決するには、クラス内で __eq__ メソッドをオーバーライドし、独自の等価判定ロジックを定義します。
class Integer:
def __init__(self, number):
self.number = number
def __eq__(self, other):
if isinstance(self, other.__class__):
return self.__dict__ == other.__dict__
return False
n1 = Integer(1)
n2 = Integer(1)
print bool(n1 == n2)
print bool(n1 != n2)
出力:
True
True
この例では、isinstance() で相手が同じクラスのインスタンスかどうかを確認し、__dict__(インスタンス属性の辞書)同士を比較することで、属性値が一致していれば True を返すようにしています。
Python 2.x と Python 3.x の違い
Python 2.x の場合は、不等号演算子 != に対応するため、__ne__ メソッドも併せてオーバーライドする必要があります。
一方、Python 3.x ではこの作業は不要です。公式ドキュメントによると、以下の仕様になっています。
デフォルトでは、__ne__()は__eq__()に処理を委譲し、その結果がNotImplementedでない限り結果を反転して返す。比較演算子の間にそれ以外の暗黙的な関係は存在しない。例えば、(x < y or x == y)が真であっても、x <= yが真であることは保証されない。
まとめ
- カスタムクラスの
==比較は、デフォルトではオブジェクトIDによる比較になるため、値が同じでもFalseが返る。 __eq__をオーバーライドすることで、属性値などに基づいた独自の等価判定を実装できる。- Python 3.x では
__ne__が自動的に__eq__の逆を返すため、オーバーライドは不要。
-
WindowsでPythonを使う方法|インストールから実行・モジュール導入まで完全解説
初心者にも学びやすいプログラミング言語の代表格として、Pythonは世界中の何百万人ものコーダーに選ばれています。学習のハードルが低く、Windows・macOS・Linuxなど主要なOSすべてでサポートされており、Webサイト開発からデスクトップゲーム制作まで、幅広いプロジェクトに活用できるのが魅力です。 macOSやLinuxではPythonが最初からインストールされていることが多い一方、Windowsではいくつか追加の手順を踏む必要があります。この記事では、WindowsでPythonをインストールし、実際に使い始めるまでの流れをわかりやすく解説します。 WindowsへのPyt
-
PythonのTkinterでスレッドを使う方法|threadingモジュールによる非同期処理の基本
Tkinterでは、スレッド(Threading)を活用することで、複数の関数を同時に実行できます。これにより、アプリケーション内の処理を非同期で動かすことが可能になります。 Pythonでスレッドを使用するには、まずthreadingモジュールをインポートし、そのThreadクラスを継承した新しいクラスを定義します。そして、クラス内でrunメソッドをオーバーライドし、実行したい処理をその中に記述します。 つまり、スレッドを使えば複数の作業を並行して進めることができます。Tkinterアプリケーションでスレッドを実現する際は、Thread()関数を利用します。 ここでは、「一定時間スリープした