Подтвердить что ты не робот

Могу ли я получить объект python из его адреса памяти?

Я изучаю, как использовать Qt с PyQt, и у меня есть QTabelView с StandardItemModel. Я успешно заполнил модель и подключил сигнал itemChanged к слоту. Я бы хотел пообщаться с любым объектом, возвращаемым в IPython, поэтому в настоящее время у меня есть строка:

def itemChangedSlot(epw, item):
    new_data = item.data()
    print new_data
    print item

который печатает

<PyQt4.QtGui.QStandardItem object at 0x07C5F930>
<PyQt4.QtCore.QVariant object at 0x07D331F0>

В сеансе IPython можно получить объект, используя этот адрес памяти? Я ничего не вижу в Google, может быть, у меня нет моей терминологии?

4b9b3361

Ответ 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, делая это, чем делать что-нибудь полезное, но делать это не может, и вам может быть интересно экспериментировать с ним.

Ответ 2

Вам необходимо сохранить ссылку на объект (т.е. назначить ее переменной или сохранить в списке).

Нет языковой поддержки для перехода от адреса объекта непосредственно к объекту (т.е. разыменование указателя).