1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonでインスタンスを比較するために__eq__を実装するときの注意点

Posted at

概要

Pythonでインスタンスを比較するとき、__eq__メソッドを使いたいことがある。
独自の方法で複数のインスタンスが同じ
か確認したいためだ。

ただ、この**__eq__メソッドをオーバーライドした時は、同時に__hash__**メソッドについても考える必要がある。
__eq__をオーバーライドすると、デフォルトでは__hash__がNoneを返すためだ。

もし、__eq__メソッドをオーバーライドしたオブジェクトをディクショナリのキーセットで使うときなど(※)は**__hash__**メソッドもオーバーライドする。
※ハッシュ可能オブジェクトの場合

__eq__メソッドをオーバーライドしない場合

example_not_override.py

class TestNotEq:
    def __init__(self):
        self.a = "a"

test_not_eq_1 = TestNotEq()
test_not_eq_2 = TestNotEq()

test_not_eq_1 == test_not_eq_2
Out: False

test_not_eq_1.__hash__()
Out: -9223371891910350837

test_not_eq_2.__hash__()
Out: -9223371891910350809

この場合、self.aに同じ値が入っているインスタンスtest_not_eq_1test_not_eq_2==で比較するとFalseとなる。

__eq__メソッドをオーバーライドした場合

example_override.py

class TestEq:
    def __init__(self):
        self.a = "a"
    def __eq__(self, other):
        return self.a == other.a

test_eq_1 = TestEq()
test_eq_2 = TestEq()

test_eq_1 == test_eq_2
Out: True

test_eq_1.__hash__()
Traceback (most recent call last):
  File "C:\Python\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3326, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-7-10d68bdb2b74>", line 1, in <module>
    test_eq_1.__hash__()
TypeError: 'NoneType' object is not callable

==での比較結果はTrueとなるが、__hash__メソッドの呼び出しは失敗する。

これは__hash__Noneになっているためである。


test_eq_1.__hash__ == None
Out: True

対応 >>> __hash__メソッドをオーバーライドする

example_override_hash.py
class TestEq:
    def __init__(self):
        self.a = "a"

    def __eq__(self, other):
        return self.a == other.a

    def __hash__(self):
        return super().__hash__()

参考

Python Document __hash__

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?