CPython の同一オブジェクト ID について
CPython では、組み込み関数 id() はオブジェクトのメモリ アドレスを表す一意の整数を返します。 。興味深いことに、次の例に見られるように、特定の状況下では 2 つの異なるオブジェクトが同じ ID を持つことがあります。
<code class="python">tuple1 = () tuple2 = () dict1 = {} dict2 = {} list1 = [] list2 = [] # Tuples are immutable assert(id(tuple1) == id(tuple2)) # Dicts are mutable assert(id(dict1) != id(dict2)) # Lists are mutable too assert(id(list1) != id(list2)) # Unexpectedly, empty dicts and lists have the same ID assert(id({}) == id({})) assert(id([]) == id([]))</code>
動作の背後にある理由
この特殊なこの現象は、CPython のメモリ アロケーターの実行時の動作と、オブジェクトの作成と破棄を処理する方法によって発生します。 id({}) が呼び出されると、CPython は新しい辞書オブジェクトを作成し、それをメモリ内の一時的な場所に割り当てます。ただし、この一時オブジェクトは、id() 関数によって ID が返された直後に破棄されます。次の id({}) が呼び出されるとき、新しい辞書が前の辞書と同じメモリ位置に作成される可能性があり、その結果、これらのオブジェクトは別個であるにもかかわらず、同じ ID になります。
この推論は次のとおりです。これは、次のシーケンスで観察される動作によってさらに裏付けられます。
<code class="python">id([]) 4330909912 x = [] id(x) 4330909912 id([]) 4334243440</code>
可変性とキャッシュの影響
この動作では、可変性が間接的な役割を果たすことに注目する価値があります。可変オブジェクト (リストやディクショナリなど) はコード オブジェクト キャッシュの対象外ですが、不変オブジェクト (空のタプルや特定の文字列など) は対象となります。これは、同じコード オブジェクト内でこれらの不変オブジェクトが再利用され、異なる不変オブジェクトに同じ ID が割り当てられる可能性があることを意味します。
ID の一意性とオブジェクトの有効期間
要約すると、オブジェクトの ID はその存続期間中のみ一意です。オブジェクトが破棄されるか、オブジェクトが作成される前に、別のオブジェクトに同じ ID が割り当てられる場合があります。この動作は、CPython におけるオブジェクト ID の一時的な性質と、基礎となる Python 実装のコンテキストにおけるメモリ割り当てとオブジェクト作成のダイナミクスを理解することの重要性を強調しています。
以上がCPython の 2 つの異なるオブジェクトが、同じオブジェクトではないにもかかわらず、同じ ID を持つことができるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。