Python

【Python】オブジェクトの識別値(ID)について

この記事では、Python のオブジェクトの識別値(ID)について解説します。

ID とは、オブジェクトが生成された時に付けられる番号のことでオブジェクトごとに異なる ID を持っています。

ID を取得する

任意のオブジェクトの ID を取得するには id()関数を使います。

id(object)

試しに適当なオブジェクトの ID を調べてみます。

num = 1
print(id(num))
# 140664210856240

num = 2
print(id(num))
# 140664210856272

vals = []
print(id(vals))
# 140664213163968

vals.append(1)
print(id(vals))
# 140664213163968

リストや辞書などのミュータブルなオブジェクトは、要素を追加・削除・変更しても ID は変わりません。

ミュータブルとイミュータブル

ID を比較する

オブジェクトの ID を比較するには is演算子 を使います。

n = None

print(n is None)

実行結果

True

None などの定数は、1つしかオブジェクトが存在しないので is演算子で比較することができます。

True などにも使用可能ですが Trueとして認識される値と比較できなくなるので注意。

n = True

print(n is True)
print(n is 1)
print(n == 1)

実行結果

True
False
True

同じ ID を参照するオブジェクト

少し補足的なことですが、イミュータブルな型の同じ値のインスタンスが複数ある場合、同じ ID を参照することがあります。

例えば、int型 で同じ値のインスタンスを生成して ID を比較してみます。

num1 = 10
num2 = 10

# is演算子 で ID が同じかどうか調べる
print(num1 is num2)

実行結果

True

同じ ID を参照していました。

int型は、メモリ内に -5~256 までの整数がいつでも使えるようにあらかじめ用意されています。なので、新しいオブジェクトを生成しておらず、すでに用意されているオブジェクトを参照するので id が同じなります。

しかし、他のイミュータブルな型や範囲外(-5~256以外)の int型 の値でも同じ ID を参照します。

i1 = 257
i2 = 257
print(i1 is i2)
>> True

f1 = 1.5
f2 = 1.5
print(f1 is f2)
>> True

t1 = (1, 2, 3)
t2 = (1, 2, 3)
print(t1 is t2)
>> True

これは、インタープリタによって同じ値のオブジェクトは同じオブジェクトを使うように最適化されているからです。

ただし、例外としてミュータブルな要素が格納されたタプルは異なる id を参照します。

t1 = (1, 2, 3, [])
t2 = (1, 2, 3, [])
print(t1 is t2)
>> False