2015年11月20日

is演算子はimmutable変数に使わないこと

is演算子の注意点について述べます。


Python にはビルトインの演算子として is があります。これは変数が同一かどうかを判定するもので、動作は id(lhs) == id(rhs) と同値です。
この is演算子を immutable変数に対して使うと、奇妙な結果になります。
(※ 以下の例はある環境での動作結果です。どの環境でも同じ結果になるとは限りません。)

>>> a = 'abc'

>>> a is 'abc'
True

>>> a is ('a' + 'b' + 'c')
True

>>> a is 'abc'.lower()
False

出てくる文字列はどれも同一ではない文字列です(値はどれも 'abc' ですが)。しかし、is演算子の結果は True であったり False であったりしています。
この結果は、Python がキャッシュを持っていることが原因です。そもそも immutable変数は常時値渡しですから、a is aとしない限り is演算子の結果は常に False となるはずです。しかし、多くの Python の実装では高速化のためにキャッシュを用いています。そして、変数が同じキャッシュを指していれば、それらの変数は同一と見なされます。

キャッシュが使われているのかどうか、キャッシュがどのように使われるのか、などは Python の実装に依存しますので、immutable変数に対して is演算子を使った場合の結果は一定となりません。
よって、is演算子は immutable変数に対して使わないこと、というのがここでの結論となります。



もう一歩進めて言うと、上記の問題もあり、is演算子の使い道はそれほど多くありません。
事実上以下の2つだけと言えます。

  • Noneチェック
  • 自己代入チェック
それぞれの内容については、項を改めて説明します。

0 件のコメント:

コメントを投稿