Pythonのis演算子と==演算子の違い

この記事を書いた動機

Pythonはなんと言っても英語っぽく書けるのが最大の利点なんだから全部isでいいんじゃね?と思って本当それで正しいのか確認しようと思った事が始まり。

実際の仕様

「初めてのPython第3版」のP200によると

オブジェクトが「同等」であるかの比較には==演算子、オブジェクトが「同一」であるかの比較にはis演算子を使う

らしい。

ということでテスト

自分はこういった仕様の確認をする場合はお決まりで仕様化テスト*1を書いてリポジトリに放り込むなり、Wikiに転記するということをしています。
書いたテストと実行結果が以下。
ちなみに環境はUbuntu10.10, Python2.6.6です。

#-*- coding:utf-8 -*-

import unittest

class EqualAndIsOperatorTest(unittest.TestCase):

    def test_numeric(self):
        self.assert_(1 is 1)
        self.assert_(1 is not 2)
        self.assert_(1 is not 1.0)

        self.assert_(1 == 1)
        self.assert_(1 != 2)
        self.assert_(1 == 1.0)

    def test_string(self):
        self.assert_(u'hoge' is not 'hoge')

        self.assert_(u'hoge' == 'hoge')

    def test_sequence(self):
        list_a = [1,2,3]
        list_b = [1,2,3]

        self.assert_(list_a is not list_b)
        self.assert_(list_a ==list_b)

        list_c = [4,5,6]

        self.assert_(list_a is not list_b)
        self.assert_(list_a != list_c)

        list_a = list_b
        self.assert_(list_a is list_b)
        self.assert_(list_a ==list_b)

if __name__ == '__main__':
    unittest.main()

続けて実行結果。

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

うん、まあエラーがないってだけなんだけど。

結論

「実際の仕様」に書いてあったとおりインスタンス同一の演算がis、値同一の演算が==です。
まあ==って__eq__()をオーバーライドすれば独自の定義できますからねー。

Javaはequals()で同値比較、==でインスンタンス同一のチェックなのでJava知ってる人には逆ですよーというとわかり易いんだろうか。

目標達成率

4/52。
若干遅いペースだ・・・

*1:元々はレガシーコードを改善するための手法。詳細はレガシーコード改善ガイドを参照。