Python PR

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

記事内に商品プロモーションを含む場合があります

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

IDとは、オブジェクトが生成された時に付けられる番号のことでオブジェクトごとに異なるIDを持っています。C言語のアドレスに似ていますが、IDから値にアクセスすることはできません。

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を比較する

オブジェクトの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