Pythonのid()関数は、オブジェクトの「識別子」を返します。オブジェクトの識別子は、そのオブジェクトのライフタイム中に一意で一定であることが保証されている整数です。ライフタイムが重ならない2つのオブジェクトは、同じid()の値を持つ場合があります。CPythonの実装では、これはメモリ内のオブジェクトのアドレスです。
Pythonのid()
Pythonは、文字列、整数、タプルなどのよく使われるデータ型のid()の値をキャッシュします。したがって、値が同じであれば、複数の変数が同じオブジェクトを参照し、同じid()の値を持つことがあります。例を使って確認しましょう。
# 整数
a = 10
b = 10
c = 11
d = 12
print(id(a))
print(id(b))
print(id(c))
print(id(d))
出力:
4317900064
4317900064
4317900096
4317900128
‘a’と‘b’のid()の値が同じであることに注意してください。彼らは同じ整数値を持っています。次に、文字列とタプルでも同様の動作をするか確認してみましょう。
# tuples
t = ('A', 'B')
print(id(t))
t1 = ('A', 'B')
print(id(t1))
# strings
s1 = 'ABC'
s2 = 'ABC'
print(id(s1))
print(id(s2))
出力:
4320130056
4320130056
4320080816
4320080816
出力からわかるように、Pythonは文字列とタプルのオブジェクトをキャッシュし、メモリスペースを節約するために使用しています。
キャッシングは不変オブジェクトでのみ機能します。整数、文字列、タプルは不変ですので、Pythonの実装はキャッシングを使用してメモリスペースを節約し、パフォーマンスを向上させることができます。
われわれは、辞書が不変でないことを知っていますが、要素が同じでも異なる辞書に対してid()が異なるかどうかを見てみましょうか?
# dict
d1 = {"A": 1, "B": 2}
d2 = {"A": 1, "B": 2}
print(id(d1))
print(id(d2))
出力:
4519884624
4519884768
思った通り、辞書オブジェクトは異なるid()値を返し、ここにはキャッシュがないようです。
Pythonのカスタムオブジェクトのid()
カスタムオブジェクトのid()値を取得する簡単な例を見てみましょう。
class Emp:
a = 0
e1 = Emp()
e2 = Emp()
print(id(e1))
print(id(e2))
出力:
4520251744
4520251856
まとめ
Pythonのid()値は、オブジェクトごとに一意で一定であることが保証されています。これを使用して、2つのオブジェクトがメモリ内の同じオブジェクトを参照しているかどうかを確認できます。
完全なPythonスクリプトとその他のPythonの例については、当社のGitHubリポジトリをご覧ください。
参考:公式ドキュメント
Source:
https://www.digitalocean.com/community/tutorials/python-id