Python 逆引き集 | Python基礎・実行環境:id()を使う

Python Python
スポンサーリンク
スポンサーリンク
  1. id()を使うとはどういうことか
  2. id()の基本的な使い方をステップバイステップで確認する
    1. まずは「番号を見てみる」
    2. リストで試してみる
    3. 同じオブジェクトを参照している場合
  3. id()とisの関係を深掘りする
    1. isは「idが同じかどうか」を比較する演算子
    2. ==との違いをもう一度整理する
  4. ミュータブルとイミュータブルの挙動をid()で体感する
    1. ミュータブル(変更可能)なオブジェクトの例:リスト
    2. イミュータブル(変更不可)なオブジェクトの例:整数
  5. Pythonの「再利用されるオブジェクト」とid()
    1. 小さな整数や短い文字列は再利用されることがある
  6. id()が役立つ具体的な場面
    1. 1. デバッグで「どのオブジェクトを触っているか」を確認する
    2. 2. 関数に渡したオブジェクトが同じものか確認する
    3. 3. キャッシュや設定オブジェクトの同一性確認
  7. セキュリティと品質の観点から見たid()の重要性
    1. 共有オブジェクトによる予期せぬ副作用
    2. Noneや特別なオブジェクトの扱い
  8. id()を使うときの注意点(重要ポイントを整理)
    1. 1. id()は「値の比較」には使わない
    2. 2. Pythonの内部最適化に依存しない
    3. 3. ミュータブルとイミュータブルの違いを意識する
  9. id()のテンプレートと練習用コード
    1. オブジェクトの識別番号を確認するテンプレート
    2. 同じオブジェクトかどうか確認するテンプレート
    3. ミュータブルの挙動を確認する練習コード
    4. イミュータブルの挙動を確認する練習コード
  10. まとめ

id()を使うとはどういうことか

Pythonの id() 関数は、「その値(オブジェクト)が、Pythonの内部でどれと認識されているか」を知るための道具です。 もう少し噛み砕くと、「同じように見える2つの値が、本当に同じものなのか、それともたまたま中身が同じ別物なのか」 を見分けるための“識別番号”を返してくれる関数だと思ってください。

初心者の方にとっては、最初は少し抽象的に感じるかもしれませんが、ミュータブル(変更可能)なオブジェクトの挙動や、is== の違いを理解するうえで、id()は非常に役立ちます。

id()の基本的な使い方をステップバイステップで確認する

まずは「番号を見てみる」

a = 10
b = 10

print(id(a))
print(id(b))
Python

ここで表示される数字は、Pythonが内部で「このオブジェクトはこれ」と識別するための番号です。 同じ値でも、同じ番号になる場合と、違う番号になる場合があります。

リストで試してみる

x = [1, 2, 3]
y = [1, 2, 3]

print(id(x))
print(id(y))
Python

多くの場合、xy は「中身は同じだけれど、別々に作られたリスト」なので、idは異なります。 ここから分かるのは、「見た目が同じでも、オブジェクトとしては別物になりうる」ということです。

同じオブジェクトを参照している場合

lst = [1, 2, 3]
alias = lst

print(id(lst))
print(id(alias))
Python

この場合は、2つの変数が同じリストを指しているので、idは完全に一致します。 「変数が違っても、指しているオブジェクトが同じならidも同じ」という感覚を持っておくと良いです。

id()とisの関係を深掘りする

isは「idが同じかどうか」を比較する演算子

Pythonの is 演算子は、内部的には「idが同じかどうか」を見ています。

a = [1, 2]
b = a

print(a is b)          # True
print(id(a) == id(b))  # True
Python

このように、is は「同じオブジェクトかどうか」を判定するための構文であり、 id()で得られる識別番号が同じかどうかをチェックしていると考えると理解しやすいです。

==との違いをもう一度整理する

x = [1, 2]
y = [1, 2]

print(x == y)  # True  → 中身が同じ
print(x is y)  # False → 別のオブジェクト
Python
  • == は「値が同じかどうか」
  • is は「同じオブジェクトかどうか」

そして is の裏側には、id()による「同一性」の判定がある、という構造です。

ミュータブルとイミュータブルの挙動をid()で体感する

ミュータブル(変更可能)なオブジェクトの例:リスト

nums = [1, 2, 3]
print(id(nums))

nums.append(4)
print(id(nums))
Python

リストは「中身を変更しても同じオブジェクトのまま」なので、idは変わりません。 これは、「同じ箱の中身が変わっただけで、箱そのものは同じ」というイメージです。

イミュータブル(変更不可)なオブジェクトの例:整数

n = 10
print(id(n))

n += 1
print(id(n))
Python

整数はイミュータブルなので、n += 1 をすると「新しい整数オブジェクト」が作られます。 そのため、idは別の番号になります。 ここから分かる重要なポイントは、「イミュータブルな値を“変更”するとき、実際には新しいオブジェクトに差し替わっている」ということです。

Pythonの「再利用されるオブジェクト」とid()

小さな整数や短い文字列は再利用されることがある

Pythonは内部的な最適化として、よく使われる小さな整数や短い文字列を再利用することがあります。

a = 10
b = 10
print(id(a), id(b))  # 同じになることが多い

s1 = "abc"
s2 = "abc"
print(id(s1), id(s2))  # これも同じになることが多い
Python

この挙動は「メモリ節約と高速化」のためですが、 「isで値の比較をしてはいけない」という重要な注意点にもつながります。

値の比較には必ず == を使い、is や id() は「同じオブジェクトかどうか」を確認するときだけ使う、というルールを持っておくと安全です。

id()が役立つ具体的な場面

1. デバッグで「どのオブジェクトを触っているか」を確認する

複数の変数が同じリストや辞書を参照しているとき、意図せず片方の変更がもう片方に影響することがあります。

users = [{"name": "Taro"}]
alias = users

print(id(users), id(alias))  # 同じ

alias.append({"name": "Hanako"})
print(users)  # usersにも追加されている
Python

こうした「参照の共有」を理解するために、id()は非常に有効です。

2. 関数に渡したオブジェクトが同じものか確認する

def modify(data):
    print("inside:", id(data))
    data.append(999)

nums = [1, 2, 3]
print("before:", id(nums))
modify(nums)
print("after:", id(nums))
Python

関数内でも同じidが表示されることから、 「関数に渡したリストは、コピーではなく同じオブジェクトが渡されている」 ということが分かります。

3. キャッシュや設定オブジェクトの同一性確認

if config is default_config:
    print("デフォルト設定を使用しています")
Python

このように、「本当に同じ設定オブジェクトを使っているか」を確認する場面でも、id()とisの概念が役立ちます。

セキュリティと品質の観点から見たid()の重要性

共有オブジェクトによる予期せぬ副作用

ミュータブルなオブジェクト(リスト・辞書など)が、意図せず複数箇所で共有されていると、 ある場所での変更が別の場所に影響し、バグやセキュリティ上の問題につながることがあります。

id()でオブジェクトの同一性を確認することで、 「どこかで同じオブジェクトを使い回していないか」 を検証でき、予期せぬ副作用を防ぎやすくなります。

Noneや特別なオブジェクトの扱い

None はPythonにおける「唯一の特別なオブジェクト」であり、 value is None という書き方が推奨されます。

これは、「idが唯一であるオブジェクトを、同一性で判定する」という考え方に基づいています。 id()の概念を理解していると、この理由も自然に腑に落ちるはずです。

id()を使うときの注意点(重要ポイントを整理)

1. id()は「値の比較」には使わない

if id(a) == id(b):  # 値の比較には不適切
    ...
Python

値が同じかどうかを知りたいときは、必ず == を使います。 id()は「同じオブジェクトかどうか」を知りたいときだけ使うものです。

2. Pythonの内部最適化に依存しない

小さな整数や短い文字列が再利用される挙動は、Pythonのバージョンや実装によって変わる可能性があります。 そのため、「isで値の比較をする」コードは、将来の挙動に依存する危険な書き方になります。

3. ミュータブルとイミュータブルの違いを意識する

  • ミュータブル:中身を変えてもidは同じ
  • イミュータブル:中身を変えると新しいオブジェクトになり、idが変わる

この違いを理解しておくと、 「なぜこの変数を変更したら別の場所の値も変わったのか?」 という疑問に対して、冷静に原因を追えるようになります。

id()のテンプレートと練習用コード

オブジェクトの識別番号を確認するテンプレート

print("value:", value, "id:", id(value))
Python

同じオブジェクトかどうか確認するテンプレート

if id(a) == id(b):
    print("同じオブジェクトです")
else:
    print("別のオブジェクトです")
Python

ミュータブルの挙動を確認する練習コード

lst = [1, 2, 3]
print("before:", id(lst))

lst.append(4)
print("after :", id(lst))
Python

イミュータブルの挙動を確認する練習コード

s = "abc"
print("before:", id(s))

s += "d"
print("after :", id(s))
Python

まとめ

  • id()は「オブジェクトの同一性」を表す識別番号を返す関数です。
  • is は「idが同じかどうか」を比較する演算子であり、値ではなくオブジェクトそのものを比較します。
  • ミュータブルとイミュータブルで、変更時のidの挙動が異なることを体感すると、Pythonのオブジェクトモデルがよく理解できます。
  • 値の比較には必ず == を使い、id()やisは「同じオブジェクトかどうか」を確認したいときだけ使うのが安全です。
  • 参照の共有や予期せぬ副作用を見抜くために、id()はデバッグやセキュリティの観点でも非常に有用です。

このあたりを押さえておくと、「Pythonはすべてがオブジェクト」という言葉の意味が、より具体的に見えてくるはずです。

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