私が他の場所で書いたように:
id
現在存在する要素のうち、その要素に固有の番号としてのみ定義されます。一部の Python 実装 (実際、CPython を除くすべての主要な実装) は、メモリ アドレスを返しません。
%~> pypy
Python 2.7.3 (480845e6b1dd219d0944e30f62b01da378437c6c, Aug 08 2013, 17:02:19)
[PyPy 2.1.0 with GCC 4.8.1 20130725 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``arguably, everything is a niche''
>>>> a = 1
>>>> b = 2
>>>> c = 3
>>>> id(a)
9L
>>>> id(b)
17L
>>>> id(c)
25L
したがって、それがメモリアドレスであることを保証する必要があります。さらに、このため、特に元のオブジェクトが削除された場合にマップ先のオブジェクトが変更される可能性があるため、Python はid → object
マッピングを提供しません。id
を保持している理由を尋ねる必要がありますid
。スペース上の理由がある場合は、コンテナーは実際には項目への参照[a, a, a, a, a]
を保持するため、実際には よりもスペースが少ないことに注意してください[id(a), id(a), id(a), id(a), id(a)]; a
。
関連するすべてのアイテムdict
のを作成して保存することも検討できます。{id: val}
これはval
生き続けるので、weakref
s を使用してval
s をガベージコレクションできるようにすることができます。が必要な場合は使用しweakref
weakref
てください。
基本的には、プラットフォームに依存しない信頼できるソリューションがないためです。
私たちがオブジェクトとそのアドレスを与える何かを持っているのは気になります
次に、そうではないことを覚えておいてください。CPythonid
は、アドレスが一意であるという (正しい) 仮定の下でのみ最適化します。is は定義されていないため、アドレスとして扱わないでください。
なぜこの決定が下されたのですか?
もし私たちが彼らのものにアクセスするid
としたら、初期化されていないものにアクセスするなど、あらゆる種類のばかげたことを行うことができるからです. また、インタープリターがアドレスを移動して物事を最適化するのを防ぎます (項目にメモリーアドレスが必要な場合、PyPy のような JIT コンパイラーはそれほど簡単には存在できませんでした)。さらに、アイテムが生きているか、同じアイテムでさえあるという保証はありません。
参照が整数 (参照 + 数値オブジェクト) よりも少ないスペースしか占有しないweakref
場合、常に正しいことを行う参照 (または必要に応じて) を使用しないだけでは意味がありません。