Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get a python object from its memory address?

I'm learning how to use Qt with PyQt, and I have a QTabelView with a StandardItemModel I've populated the model successfully and hooked up the itemChanged signal to a slot. I'd l'd like to mess around with whatever object is returned in IPython, so currently I have the line:

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

which prints

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

In the IPython session is it possible to get the object using this memory address? I'm not seeing anything on Google, maybe I don't have my terminology right?

like image 838
Erotemic Avatar asked Apr 01 '13 18:04

Erotemic


People also ask

How do you call a memory address in Python?

Method 1: Using id() We can get an address using the id() function. id() function gives the address of the particular object.

What is the Python function that returns the memory address of an object?

You'll need a couple of tools from the Python standard library: id() returns the object's memory address.

How do you print the memory address of an object in Python?

Method 1: Find and Print Address of Variable using id() We can get an address using id() function, id() function gives the address of the particular object.

Where are Python objects stored in memory?

No, they are in a different memory called “Heap Memory” (also called the Heap). To store objects, we need memory with dynamic memory allocation (i.e., size of memory and objects can change). Python interpreter actively allocates and deallocates the memory on the Heap (what C/C++ programmers should do manually!!!


2 Answers

You need to hold a reference to an object (i.e. assign it to a variable or store it in a list).

There is no language support for going from an object address directly to an object (i.e. pointer dereferencing).

like image 179
Raymond Hettinger Avatar answered Oct 19 '22 20:10

Raymond Hettinger


You're almost certainly asking the wrong question, and Raymond Hettinger's answer is almost certainly what you really want.

Something like this might be useful trying to dig into the internals of the CPython interpreter for learning purposes or auditing it for security holes or something… But even then, you're probably better off embedding the Python interpreter into a program and writing functions that expose whatever you want into the Python interpreter, or at least writing a C extension module that lets you manipulate CPython objects.

But, on the off chance that you really do need to do this…

First, there is no reliable way to even get the address from the repr. Most objects with a useful eval-able representation will give you that instead. For example, the repr of ('1', 1) is "('1', 1)", not <tuple at 0x10ed51908>. Also, even for objects that have no useful representation, returning <TYPE at ADDR> is just an unstated convention that many types follow (and a default for user-defined classes), not something you can rely on.

However, since you presumably only care about CPython, you can rely on id:

CPython implementation detail: This is the address of the object in memory.

(Of course if you have the object to call id (or repr) on, you don't need to dereference it via pointer, and if you don't have the object, it's probably been garbage collected so there's nothing to dereference, but maybe you still have it and just can't remember where you put it…)

Next, what do you do with this address? Well, Python doesn't expose any functions to do the opposite of id. But the Python C API is well documented—and, if your Python is built around a shared library, that C API can be accessed via ctypes, just by loading it up. In fact, ctypes provides a special variable that automatically loads the right shared library to call the C API on, ctypes.pythonapi.

In very old versions of ctypes, you may have to find and load it explicitly, like pydll = ctypes.cdll.LoadLibrary('/usr/lib/libpython2.5.so') (This is for linux with Python 2.5 installed into /usr/lib; obviously if any of those details differ, the exact command line will differ.)

Of course it's much easier to crash the Python interpreter doing this than to do anything useful, but it's not impossible to do anything useful, and you may have fun experimenting with it.

like image 13
abarnert Avatar answered Oct 19 '22 20:10

abarnert