Pythonでid関数を使ってオブジェクトのIDを調べる方法

スポンサーリンク

本日は、Pythonのid()関数についてご紹介します。

id()関数は、Pythonの任意のオブジェクトのIDを返します。

これは、異なるオブジェクトに対して整数の識別番号を返します。

基礎となるCPythonの実装では、id()関数をメモリ上のオブジェクトのアドレスとして使用します。

いくつかの例を使って、もう少し理解しましょう。

スポンサーリンク

Pythonにおけるid()関数の基本構文

この関数は、Pythonの任意のオブジェクト(整数、浮動小数点、文字列、リスト、クラス、関数、ラムダなど)を受け取り、整数のidを返します。

val = id(object)

Pythonでid()を使う

オブジェクトの id は、Python がそれらの変数の値をキャッシュするのに便利です。

また、これは複数の変数が同じオブジェクトを参照している場合にも役立ちます。

a = 1233.45
b = a
 
print(id(a))
print(id(b))

結果は以下の通りです。

2775655780976
2775655780976

この場合、Pythonは参照されているオブジェクトを把握しやすいので、aのid()はbのid()と同じになります。

では、これをいくつかの簡単なPythonのオブジェクトに使ってみましょう。

print(id(103)) # Int
 
print(id(104))
 
print(id(10.25)) # Float
 
print(id('Hello from Python')) # String
 
print(id([1, 2, 3])) # List
 
print(id(lambda x: x * x)) # Lambda

結果は以下の通りです。

1658621232
1658621264
2775655780976
2775665230232
2775665206344
2775656111776

見ての通り、103と104の整数では、ID番号に32の差しかありません。

これは理にかなっています。

id()` はオブジェクトのアドレスを指すと言ったのを覚えていますか?

id(104)は整数103の次のアドレスブロックです。

Pythonの整数は4バイトで格納されるので、これは32ビットを表し、ちょうどそれが彼らのid番号の差になります。

つまり、Pythonはすべての整数のリストを、等間隔で連続したブロックに格納しているのです。

では、文字列でテストしてみましょう。

# strings
s1 = 'ABC'
s2 = 'ABC'
print(id(s1))
print(id(s2))

結果は以下の通りです。

2775656418080
2775656418080

ご覧の通り、Pythonはメモリを節約するために文字列をキャッシュしています。

キャッシュは、整数、文字列、浮動小数点数といった、Pythonの不変のオブジェクトに対してのみ機能することを忘れないでください。

タプルやリストなどは変更可能なオブジェクトなので、キャッシュはここでは機能しません。

これを証明するために、同じ要素を持つ2つのリストのidをチェックしてみましょう。

>>> l1 = [1, 2, 3, 4]
>>> l2 = [1, 2, 3 ,4]
>>> id(l1)
2775665206344
>>> id(l2)
2775665185224

この場合、リストはミュータブルなので、キャッシュは働きません。

カスタムオブジェクトで id() を使用する

id() 関数をカスタムオブジェクトに使用することもできます。

簡単な例を見てみましょう。

class Student():
    def __init__(self, name, id):
        self.name = name
        self.id = id
 
s = Student('Amit', 10)
t = Student('Rahul', 20)
 
print(id(s))
 
print(id(t))

結果は以下の通りです。

2775665179336
2775665179448

これは、オブジェクトが格納されているメモリアドレスを指しており、2つのインスタンスでは明らかに異なります!

まとめ

今回は、Pythonのid()関数の使い方について学びました。

これはPythonオブジェクトの基礎となるメモリアドレスを表し、不変のオブジェクトをキャッシュするのに便利です。

タイトルとURLをコピーしました