回答:
Pythonのマニュアルでは、これはについて言いたいことがありますid()
:
オブジェクトの「アイデンティティ」を返します。これは整数(または長整数)であり、このオブジェクトの存続期間中は一意で一定であることが保証されます。存続期間が重複しない2つのオブジェクトは、同じid()値を持つ場合があります。 (実装上の注意:これはオブジェクトのアドレスです。)
したがって、CPythonでは、これはオブジェクトのアドレスになります。ただし、他のPythonインタープリターではそのような保証はありません。
C拡張機能を作成している場合は、オブジェクトのアドレスへの直接アクセスを含む、Pythonインタープリターの内部への完全なアクセス権があることに注意してください。
lifetime
か(そしてそれが存続期間にとって何を意味するのoverlap/not overlap
でしょうか)?
この方法でデフォルトのreprを再実装できます。
def __repr__(self):
return '<%s.%s object at %s>' % (
self.__class__.__module__,
self.__class__.__name__,
hex(id(self))
)
return object.__repr__(self)
あるいは単に行うことができobject.__repr__(obj)
ます
__repr__ = object.__repr__
あり、これが機能しないさまざまな状況が存在するため、それほど簡単で__getattribute__
はありません。メモリの場所。また、Zフィルも行わないため、システムが64ビットの場合は、必要に応じてゼロを追加する必要があります。
使うだけ
id(object)
id()
@JLT を確認できます
ここには、他の回答ではカバーされないいくつかの問題があります。
まず、以下id
のみを返します:
オブジェクトの「アイデンティティ」。これは整数(または長整数)であり、その存続期間中、このオブジェクトに対して一意で一定であることが保証されています。重複しないライフタイムを持つ2つのオブジェクトは、同じ
id()
値を持つ場合があります。
CPythonでは、これはたまたまPyObject
インタープリター内のオブジェクトを表すへのポインターです。これはオンになっているのと同じことですが、明らかにポインターにはなりません。IronPythonについてはわかりませんが、この点では、CPythonよりもJythonに近いと思います。したがって、ほとんどのPython実装では、何が表示されてもそれを取得する方法はありません。object.__repr__
表示される。ただし、これはCPythonの実装の詳細にすぎず、Python全般に当てはまるものではありません。Jythonはポインターを処理せず、Java参照を処理します(もちろん、JVMはおそらくポインターとして表現しますが、GCがポインターを移動できるため、それらを表示することはできません。PyPyを使用すると、さまざまなタイプにさまざまな種類のを持たせることができますid
が、最も一般的なのは、呼び出したオブジェクトのテーブルへのインデックスですid
repr
しかし、CPythonだけに関心がある場合はどうでしょうか。結局のところ、それはかなり一般的なケースです。
さて、最初に、それがid
整数であることに気付くかもしれません。* 0x2aba1c0cf890
数値の代わりにその文字列が必要な場合は、46978822895760
自分でフォーマットする必要があります。裏では、object.__repr__
最終的にはPythonにはないprintf
の%p
形式を使用していると思いますが、いつでもこれを行うことができます。
format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')
* 3.xでは、これはint
です。2.xでは、int
ポインターを保持するのに十分な大きさである場合があります(一部のプラットフォームでは、署名された数値の問題が原因ではない可能性があります)long
。
印刷する以外に、これらのポインタでできることはありますか?確かに(ここでも、CPythonのみに関心があると仮定しています)。
すべてのC API関数は、PyObject
または関連する型へのポインターを受け取ります。これらの関連するタイプについては、を呼び出しPyFoo_Check
て、それが本当にFoo
オブジェクトであることを確認してから、でキャストでき(PyFoo *)p
ます。したがって、C拡張機能を作成している場合は、これid
がまさに必要です。
純粋なPythonコードを作成している場合はどうなりますか?pythonapi
fromを使用して、まったく同じ関数を呼び出すことができますctypes
。
最後に、他のいくつかの答えが浮上しましたctypes.addressof
。ここでは関係ありません。これは、などのctypes
オブジェクトc_int32
(およびによって提供されるような、いくつかのメモリバッファのようなオブジェクト)でのみ機能しますnumpy
。そして、そこにさえ、それはあなたにc_int32
値のアドレスを与えていません、それはあなたint32
にc_int32
ラップするCレベルのアドレスを与えています。
そうは言っても、たいていの場合、何かのアドレスが本当に必要だと思うのであれば、そもそもネイティブPythonオブジェクトが必要ではなく、ctypes
オブジェクトが必要でした。
id
それらを使用してseen
セットまたはcache
dict 内の変更可能な値を保持することを含む— id
は、ポインタであることに依存したり、何らかの方法でに関連付けたりしないでくださいrepr
。そのため、このようなコードはCPythonでのみ機能するのではなく、すべてのPython実装で機能します。
id
はそれを使用しましたが、Javaでもオブジェクトのアドレスを取得できることを意味します、それは(C)Pythonに方法がないのは奇妙に見えますそれはオブジェクトを移動しない実際に安定したgcを持っているため、アドレスは同じままです
id
必要はありません。アドレスであるかどうかに関係なく、オブジェクトのfo を使用します。たとえば、PyPyではid
、実装内の非表示のテーブルへのインデックスにすぎない場合でも、CPythonのキーと同じくらい便利ですが、(Javaのように)オブジェクトを移動できるため、ポインターは役に立ちません。メモリ。
id
、オブジェクトのがメモリ内のオブジェクトの場所へのポインターであることを明示的に文書化しています。したがって、CPython固有のコードでポインター値を使用すると(回答で説明されているように、ほとんど使用しません)、文書化されて動作することが保証されている方法を使用できます。
Torstenに応えてaddressof()
、通常のpythonオブジェクトを呼び出すことができませんでした。さらにid(a) != addressof(a)
。これはCPythonにあり、他に何も知りません。
>>> from ctypes import c_int, addressof
>>> a = 69
>>> addressof(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: invalid type
>>> b = c_int(69)
>>> addressof(b)
4300673472
>>> id(b)
4300673392
ctypes、あなたが同じことを達成することができます
>>> import ctypes
>>> a = (1,2,3)
>>> ctypes.addressof(a)
3077760748L
ドキュメンテーション:
addressof(C instance) -> integer
Cインスタンスの内部バッファーのアドレスを返します
CPythonでは現在id(a) == ctypes.addressof(a)
、ただしctypes.addressof
、次の場合は各Python実装の実際のアドレスを返す必要がある
編集:ctypesのインタープリター非依存性に関する情報を追加
TypeError: invalid type
、Python 3.4で試した結果です。
あなたはその目的に適した何かを得ることができます:
id(self)
私はこれが古い質問であることを知っていますが、まだプログラミングをしている場合は、最近のpython 3で...文字列の場合、これを行う簡単な方法があることがわかりました。
>>> spam.upper
<built-in method upper of str object at 0x1042e4830>
>>> spam.upper()
'YO I NEED HELP!'
>>> id(spam)
4365109296
文字列変換は、メモリ内の場所にも影響しません。
>>> spam = {437 : 'passphrase'}
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'
>>> str(spam)
"{437: 'passphrase'}"
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'
id(object)
デフォルトのCPython実装でオブジェクトのアドレスを取得することは事実ですが、これは一般的に役に立たない... 純粋なPythonコードからのアドレスでは何もできません。
実際にアドレスを使用できるのは、C拡張ライブラリからのみです...この場合、Pythonオブジェクトは常にCポインターとして渡されるため、オブジェクトのアドレスを取得するのは簡単です。
ctypes
標準ライブラリの組み込みツールキットを使用しない限り。その場合、アドレスを使用してあらゆる種類のことを実行できます:)