Hier gibt es einige Probleme, die in keiner der anderen Antworten behandelt werden.
Erstens, gibt id
nur zurück:
die "Identität" eines Objekts. Dies ist eine Ganzzahl (oder lange Ganzzahl), die für dieses Objekt während seiner Lebensdauer garantiert eindeutig und konstant ist. Zwei Objekte mit nicht überlappenden Lebensdauern können denselben id()
Wert haben.
In CPython ist dies zufällig der Zeiger auf das PyObject
Objekt, das das Objekt im Interpreter darstellt. Dies wird auch object.__repr__
angezeigt. Dies ist jedoch nur ein Implementierungsdetail von CPython, nicht etwas, das für Python im Allgemeinen gilt. Jython handelt nicht mit Zeigern, sondern mit Java-Referenzen (die die JVM wahrscheinlich als Zeiger darstellt, aber Sie können diese nicht sehen - und möchten dies auch nicht, da der GC sie verschieben darf). Mit PyPy können verschiedene Typen unterschiedliche Arten haben id
, aber am allgemeinsten ist nur ein Index in einer Tabelle von Objekten, die Sie aufgerufen habenid
on, was offensichtlich kein Zeiger sein wird. Ich bin mir bei IronPython nicht sicher, aber ich würde vermuten, dass es in dieser Hinsicht eher wie Jython als wie CPython ist. In den meisten Python-Implementierungen gibt es also keine Möglichkeit, das zu erhalten, was darin angezeigt wird repr
, und es nützt nichts, wenn Sie dies getan haben.
Aber was ist, wenn Sie sich nur für CPython interessieren? Das ist schließlich ein ziemlich häufiger Fall.
Zunächst stellen Sie möglicherweise fest, dass id
es sich um eine Ganzzahl handelt. * Wenn Sie diese 0x2aba1c0cf890
Zeichenfolge anstelle der Zahl verwenden möchten 46978822895760
, müssen Sie sie selbst formatieren. Unter dem Deckmantel glaube ich, dass object.__repr__
letztendlich printf
das %p
Format verwendet wird, das Sie nicht von Python haben ... aber Sie können dies immer tun:
format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')
* In 3.x ist es ein int
. In 2.x ist dies ein int
Fall, der groß genug ist, um einen Zeiger aufzunehmen - was möglicherweise nicht auf Probleme mit signierten Nummern auf einigen Plattformen zurückzuführen ist - und ein long
anderes.
Können Sie mit diesen Zeigern etwas anderes tun, als sie auszudrucken? Sicher (wieder vorausgesetzt, Sie interessieren sich nur für CPython).
Alle C-API- Funktionen nehmen einen Zeiger auf einen PyObject
oder einen verwandten Typ. Für diese verwandten Typen können Sie einfach aufrufen PyFoo_Check
, um sicherzustellen, dass es sich wirklich um ein Foo
Objekt handelt, und dann mit umwandeln (PyFoo *)p
. Wenn Sie also eine C-Erweiterung schreiben, id
ist dies genau das, was Sie brauchen.
Was ist, wenn Sie reinen Python-Code schreiben? Sie können genau die gleichen Funktionen mit pythonapi
from aufrufen ctypes
.
Schließlich haben sich einige der anderen Antworten ergeben ctypes.addressof
. Das ist hier nicht relevant. Dies funktioniert nur für ctypes
Objekte wie c_int32
(und möglicherweise einige speicherpufferähnliche Objekte wie die von numpy
). Und selbst dort erhalten Sie nicht die Adresse des c_int32
Werts, sondern die Adresse der C-Ebene int32
, die c_int32
der Abschluss enthält.
Davon abgesehen wollten Sie meistens, wenn Sie wirklich glauben, die Adresse von etwas zu benötigen, überhaupt kein natives Python-Objekt, sondern ein ctypes
Objekt.