0

バックグラウンド

これは、ガベージ コレクションが場所の内容をいつでもクリアするためであることが最近わかりました。他の理由もあるかもしれませんが、私にはわかりません。

また、CPython ではオブジェクトの address=id であるため、C を使用してその場所を指定してオブジェクトにアクセスできることも知りました。(これについて IRC の人たちに感謝しなければなりません。) しかし、私はそれを試していません。

私はこのアドレス(id)について話している:

address = id(object_name)

またはこれかもしれません(それが役立つ場合):

hex_address = hex(id(object))

とにかく、彼らが私のためにそれを行うことができる何らかの方法を提供してくれれば、もっと良かったと思います.

実際にはそのような方法を使用したくありませんが、オブジェクトとそのアドレスを提供する何かがあるのに、その逆を行うものがないことは気になります。

質問

  • なぜこの決定が下されたのですか?
  • Python レベルでクレイジーなイントロスペクション/ハックを使用してこれを行うことはできますか? Python レベルではできないと言われましたが、確認したかっただけです。
4

2 に答える 2

8

最も簡単な答えは次のとおりです。「それは必要なく、変数への低レベルのアクセスなしでコードを維持する方が簡単だからです」。

もう少し複雑なのは、そのようなポインターでできることはすべて、Python の基本的な参照、または弱い参照 (ガベージ コレクションを禁止せずにオブジェクトを参照したい場合) でもできるということです。

「ハッキング」について:

  1. ガベージコレクターを反復処理してオブジェクトを取り出すことができます

    import gc
    
    def objects_by_id(id_):
        for obj in gc.get_objects():
            if id(obj) == id_:
                return obj
    
  2. mxtoolsを使用できます

    mx.Tools.makeref(id_)
    
  3. ctypesを使用できます

    ctypes.cast(id_, ctypes.py_object).value
    
于 2013-09-28T10:54:12.723 に答える
1

私が他の場所で書いたように:


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生き続けるので、weakrefs を使用してvals をガベージコレクションできるようにすることができます。が必要な場合使用しweakrefweakrefてください。


基本的には、プラットフォームに依存しない信頼できるソリューションがないためです。

私たちがオブジェクトとそのアドレスを与える何かを持っているのは気になります

次に、そうではないことを覚えておいてください。CPythonidは、アドレスが一意であるという (正しい) 仮定の下でのみ最適化します。is は定義されていないため、アドレスとして扱わないでください。


なぜこの決定が下されたのですか?

もし私たちが彼らのものにアクセスするidとしたら、初期化されていないものにアクセスするなど、あらゆる種類のばかげたことを行うことができるからです. また、インタープリターがアドレスを移動して物事を最適化するのを防ぎます (項目にメモリーアドレスが必要な場合、PyPy のような JIT コンパイラーはそれほど簡単には存在できませんでした)。さらに、アイテムが生きているか、同じアイテムでさえあるという保証はありません。

参照が整数 (参照 + 数値オブジェクト) よりも少ないスペースしか占有しないweakref場合、常に正しいことを行う参照 (または必要に応じて) を使用しないだけでは意味がありません。

于 2013-09-28T11:18:33.400 に答える