Pythonのプログラムで、2つの変数に 'public'
という値が設定されているものがあります。条件式の中で、比較を var1 is var2
とすると失敗しますが、var1 == var2
とすると True
を返します。
今度はPythonのインタープリタを開いて、同じ"is"の比較をすると成功します。
>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True
私はここで何を見逃しているのでしょうか?
isは同一性のテスト、
==`は同一性のテストです。あなたのコードで起こることは、インタープリタでは次のようにエミュレートされます。
>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False
これでは、両者が同じではないのも当然ですよね?
言い換えればisは
id(a) == id(b)` のことです。
これは、 'is'の比較がfalseと評価された場合、2つの異なるオブジェクトが使用されているという事実と関係があると思います。これがtrueと評価された場合、内部的には全く同じオブジェクトを使用しており、新しいオブジェクトを作成していないことを意味します。おそらく、2秒ほどのほんのわずかな時間内に作成したため、大きな時間差がないために最適化され、同じオブジェクトを使用しているのだと思います。
これが、文字列オブジェクトの値を比較する際に、is
ではなく、等号演算子==
を使うべき理由です。
>>> s = 'one'
>>> s2 = 'two'
>>> s is s2
False
>>> s2 = s2.replace('two', 'one')
>>> s2
'one'
>>> s2 is s
False
>>>
この例では、以前に別の文字列オブジェクトである s2 を 'one'と等しくしましたが、s
と同じオブジェクトではありません。これは、インタプリタが同じオブジェクトを使用しなかったためで、最初に 'one'に代入していなければ、同じオブジェクトになっていたはずです。