【Python】isでオブジェクトのアイデンティティーを比較【入門第46回】

156, 2019-09-06

目次

オブジェクトのアイデンティティーとは?

こんにちは、narupoです。

今回はオブジェクトのアイデンティティー(同一性)の比較についてやりたいと思います。
なんかカタカナで難しそうですが、内容は簡単です。
Pythonのオブジェクトはすべてアイデンティティーと言う数値を持っています。
この数値を比較するのが同一性の比較です。

具体的には↓を見ていきます。

  • オブジェクトのアイデンティティーの取得

  • isによるアイデンティティーの比較

  • is notによるアイデンティティーの比較

  • isと==の違い

  • isの使用例

オブジェクトのアイデンティティーの取得

オブジェクトとは、Pythonで出てくる全てのモノを表します。
変数はオブジェクトですし、クラスのインスタンスもオブジェクト、文字列も数値もTrueもオブジェクトです。
これらのオブジェクトはすべてアイデンティティーという数値を持っています。
この数値は、オブジェクトが作られるときに割り振られ、オブジェクトの比較で使われることがあります。

このオブジェクトのアイデンティティーを取得するには、id関数を使います。
↓はTrueのアイデンティティーを出力するコードです。

print(id(True))

↑のコードの実行結果は↓のようになります(この結果は環境によって変わります)。

140712029305168

↑の数値の羅列がTrueオブジェクトが持つアイデンティティーです。
数値や文字列のアイデンティティーも↓のようにして取得できます。

print(id(1))
print(id('cat'))

アイデンティティーは唯一の値

オブジェクトのアイデンティティーはユニークなものです。
この値は被ることがありません。
オブジェクトが作られるときに、Pythonインタプリタはオブジェクトに唯一の値、アイデンティティーを割り振ります。
このアイデンティティーによってオブジェクトの同一性を比較することが可能になるのです。

「オブジェクトの同一性の比較」というのは、なんかむずかしい言葉ですが、言い換えれば「このオブジェクトとこのオブジェクトは同じもの?」という意味です。
オブジェクトが同じものか違うものかがわかれば、プログラムでオブジェクトを比較することが可能になります。

isによるアイデンティティーの比較

ラップトップとタイプライター

しかし、わざわざid関数でオブジェクトのアイデンティティーを取得して、その値を比較するのは面倒です。
これを手っ取り早く行えるのがis演算子です。
isは左のオブジェクトと右のオブジェクトが同じアイデンティティーだった時にTrueを返します。
たとえば↓のようにTrueオブジェクトを比較してみましょう。

print(True is True)

↑のコードの実行結果はTrueになります。
↑の結果から、↑の2つのTrueは同じオブジェクトであることがわかります。
ではTrueFalseはどうでしょうか。

print(True is False)

↑のコードの実行結果はFalseになります。

クラスのインスタンスの比較はどうでしょうか。
↓のようなコードがあります。

class Cat:
    pass

mike = Cat()
tama = Cat()

print(mike is tama)

↑のコードの実行結果はFalseになります。
↑のインスタンスmiketamaは違うオブジェクトだからですね。

is notによるアイデンティティーの比較

左と右のオブジェクトのアイデンティティーが違う時にTrueを得たい場合は、is notを使います。
例えば↓のようにです。

print(True is not False)

↑のコードの実行結果はTrueになります。
TrueFalseは違うオブジェクトだからですね。

is==の違い

is==は紛らわしいです。
しかしis==の違いは明確です。
その違いは↓の通りです。

  • isはオブジェクトのアイデンティティーの比較

  • ==は値の比較

たとえば↓のコードを見てみましょう。

print(True is True)
print(True == True)

↑のコードのprintはどちらもTrueを出力します。
True is Trueは、オブジェクトのアイデンティティーを比較しています。
これは

id(True) == id(True)

と同じです。
いっぽうTrue == Trueは、Trueオブジェクトが持つ値を比較しています。

以上のように、is==比較しているものが全く違います

isの使用例

ここで私がisを使う場面をご紹介します。
私がisをよく使うのは、関数の引数がNoneかどうか判定するときです。
たとえば↓のような関数を見てみましょう。

def func(x):
    print(x)

↑の関数で引数xをチェックして、xNoneの時にエラーを送出したいとします。
その場合は↓のようにします。

def func(x):
    if x is None:
        raise TypeError('x is none')
    print(x)

↑のコードを見て「別にx == Noneでもいいじゃないか」と思ったみなさんはするどい!
しかし、この場合はisのほうが適切と言えます。
なぜかと言うと、==演算子はクラスの演算子のオーバーロードで上書きして、振る舞いを変更することができるからです。
いっぽう、is演算子はその振る舞いを変えることは出来ません。
よってisを使ったほうがセキュアと言えます。

おわりに

isによるオブジェクトの同一性の比較は、厳密にオブジェクトのアイデンティティーを比較することができます。
アイデンティティーを比較することが出来ることで、私たちはオブジェクトを区別できます。
オブジェクトを区別することができるので、プログラムをより厳密に作ることが可能になります。

以上、次回に続きます。

また見てね

関連動画

スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク