Ada beberapa masalah di sini yang tidak dicakup oleh jawaban lain mana pun.
Pertama, id
hanya mengembalikan:
"identitas" suatu objek. Ini adalah bilangan bulat (atau bilangan bulat panjang) yang dijamin unik dan konstan untuk objek ini selama masa pakainya. Dua objek dengan masa hidup yang tidak tumpang tindih mungkin memiliki nilai yang sama id()
.
Dalam CPython, ini adalah penunjuk ke PyObject
yang mewakili objek dalam penafsir, yang merupakan hal yang sama yang object.__repr__
ditampilkan. Tapi ini hanyalah detail implementasi dari CPython, bukan sesuatu yang berlaku untuk Python secara umum. Jython tidak berurusan dengan pointer, ia berurusan dengan referensi Java (yang tentu saja mewakili JVM sebagai pointer, tetapi Anda tidak dapat melihat itu — dan tidak mau, karena GC diizinkan untuk memindahkannya). PyPy memungkinkan berbagai jenis memiliki jenis yang berbeda id
, tetapi yang paling umum hanyalah indeks ke dalam tabel objek yang Anda panggilid
pada, yang jelas tidak akan menjadi penunjuk. Saya tidak yakin tentang IronPython, tapi saya menduga ini lebih seperti Jython daripada seperti CPython dalam hal ini. Jadi, di sebagian besar implementasi Python, tidak ada cara untuk mendapatkan apa pun yang muncul dalam hal itu repr
, dan tidak ada gunanya jika Anda melakukannya.
Tetapi bagaimana jika Anda hanya peduli tentang CPython? Bagaimanapun, itu adalah kasus yang cukup umum.
Nah, pertama, Anda mungkin melihat itu id
adalah bilangan bulat; * jika Anda menginginkan 0x2aba1c0cf890
string itu alih-alih nomornya 46978822895760
, Anda harus memformatnya sendiri. Di bawah selimut, saya percaya object.__repr__
akhirnya menggunakan printf
's %p
format, yang Anda tidak memiliki dari Python ... tapi Anda selalu dapat melakukan hal ini:
format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')
* Dalam 3.x, ini adalah int
. Dalam 2.x, itu adalah int
jika itu cukup besar untuk memegang pointer — yang mungkin bukan karena masalah nomor yang ditandatangani pada beberapa platform — dan long
sebaliknya.
Apakah ada yang bisa Anda lakukan dengan petunjuk ini selain mencetaknya? Tentu (sekali lagi, anggap Anda hanya peduli tentang CPython).
Semua fungsi C API mengambil pointer ke tipe PyObject
atau yang terkait. Untuk jenis terkait, Anda bisa menelepon PyFoo_Check
untuk memastikan itu benar-benar Foo
objek, lalu dilemparkan dengan (PyFoo *)p
. Jadi, jika Anda menulis ekstensi C, id
itulah yang Anda butuhkan.
Bagaimana jika Anda sedang menulis kode Python murni? Anda dapat memanggil fungsi yang sama persis dengan pythonapi
dari ctypes
.
Akhirnya, beberapa jawaban lain muncul ctypes.addressof
. Itu tidak relevan di sini. Ini hanya berfungsi untuk ctypes
objek seperti c_int32
(dan mungkin beberapa objek seperti buffer memori, seperti yang disediakan oleh numpy
). Dan, bahkan di sana, itu tidak memberi Anda alamat c_int32
nilai, itu memberi Anda alamat tingkat-C int32
yang c_int32
dirangkum.
Yang sedang berkata, lebih sering daripada tidak, jika Anda benar-benar berpikir Anda perlu alamat sesuatu, Anda tidak ingin objek Python asli di tempat pertama, Anda menginginkan ctypes
objek.