Python
 Computer >> コンピューター >  >> プログラミング >> Python

【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__ の逆を返すため、オーバーライドは不要。
  1. WindowsでPythonを使う方法|インストールから実行・モジュール導入まで完全解説

    初心者にも学びやすいプログラミング言語の代表格として、Pythonは世界中の何百万人ものコーダーに選ばれています。学習のハードルが低く、Windows・macOS・Linuxなど主要なOSすべてでサポートされており、Webサイト開発からデスクトップゲーム制作まで、幅広いプロジェクトに活用できるのが魅力です。 macOSやLinuxではPythonが最初からインストールされていることが多い一方、Windowsではいくつか追加の手順を踏む必要があります。この記事では、WindowsでPythonをインストールし、実際に使い始めるまでの流れをわかりやすく解説します。 WindowsへのPyt

  2. PythonのTkinterでスレッドを使う方法|threadingモジュールによる非同期処理の基本

    Tkinterでは、スレッド(Threading)を活用することで、複数の関数を同時に実行できます。これにより、アプリケーション内の処理を非同期で動かすことが可能になります。 Pythonでスレッドを使用するには、まずthreadingモジュールをインポートし、そのThreadクラスを継承した新しいクラスを定義します。そして、クラス内でrunメソッドをオーバーライドし、実行したい処理をその中に記述します。 つまり、スレッドを使えば複数の作業を並行して進めることができます。Tkinterアプリケーションでスレッドを実現する際は、Thread()関数を利用します。 ここでは、「一定時間スリープした