Ответ 1
Ты почти наверняка задаешь неправильный вопрос, и ответ Раймонда Хеттингера почти наверняка то, что ты действительно хочешь.
Что-то вроде этого может быть полезно, пытаясь вникать в внутренности интерпретатора CPython для обучения или проверять его на наличие дыр в безопасности или что-то в этом роде... Но даже тогда вам, вероятно, лучше вложить интерпретатор Python в программу и писать функции, которые раскрывают все, что вы хотите, в интерпретаторе Python или, по крайней мере, записываете модуль расширения C, который позволяет вам манипулировать объектами CPython.
Но, вовремя, вам действительно нужно это сделать...
Во-первых, нет надежного способа даже получить адрес из repr
. Большинство объектов с полезным eval
-able представлением даст вам это вместо этого. Например, представление ('1', 1)
равно "('1', 1)"
, а не <tuple at 0x10ed51908>
. Кроме того, даже для объектов, которые не имеют полезного представления, возвращение <TYPE at ADDR>
- это просто нестационарное соглашение, в котором следуют многие типы (и значение по умолчанию для пользовательских классов), а не то, на что вы можете положиться.
Однако, поскольку вы, по-видимому, заботитесь только о CPython, вы можете положиться на id
:
Подробности реализации CPython: это адрес объекта в памяти.
(Конечно, если у вас есть объект для вызова id
(или repr
), вам не нужно разыгрывать его с помощью указателя, и если у вас нет объекта, возможно, он собрал мусор так что нечего разыгрывать, но, может быть, у вас все еще есть это и просто не могу вспомнить, где вы его положили...)
Далее, что вы будете делать с этим адресом? Ну, Python не предоставляет никаких функций, чтобы сделать противоположное от id
. Но API Python C > хорошо документирован - и если ваш Python построен вокруг общей библиотеки, к этому API C можно получить доступ через ctypes
, просто загрузив его. Фактически, ctypes
предоставляет специальную переменную, которая автоматически загружает нужную общую библиотеку для вызова C API, ctypes.pythonapi
.
В очень старых версиях ctypes
вам может потребоваться найти и загрузить его явно, например pydll = ctypes.cdll.LoadLibrary('/usr/lib/libpython2.5.so')
(это для Linux с Python 2.5, установленным в /usr/lib, очевидно, если какая-либо из этих деталей отличается, точная командная строка будет отличаться.)
Конечно, гораздо проще сбивать интерпретатор Python, делая это, чем делать что-нибудь полезное, но делать это не может, и вам может быть интересно экспериментировать с ним.