Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does python store objects in memory

Tags:

python

object

It is my understanding that a list is a block of contiguous memory locations that contain pointers to the element values in memory. As shown below:

list in memory

My question is whether its the same with objects in memory ie: suppose I have a point class with an init method implemented as follows:

class Point: 
    def __init__(self, x, y): 
        self.x = x
        self.y = y

And I create a new point object:

p = Point(4,6)

Would the pointer to p.x and the pointer to p.y be next to each other in memory?

like image 519
Teererai Marange Avatar asked Dec 24 '22 03:12

Teererai Marange


2 Answers

Python - that is, the programming language - has no concept of memory locations or pointers. So from that point of view, there is no answer to your question. Your question can only be answered for a specific implementation of python, like CPython.

That said, the answer is going to be no for pretty much every implementation of python. That's because (most) python classes store their attributes in a dictionary. We can access this dictionary through the name __dict__:

>>> Point(1, 2).__dict__
{'x': 1, 'y': 2}

Since dicts have to be efficient and have an O(1) lookup time, they are usually implemented as hash tables. The chance of x and y being right next to each other in a hash table is very slim.

Not all classes use a dictionary to store attributes, though. There are two exceptions:

  • Built-in classes like dictionaries, integers, strings, etc.
  • Classes with a __slots__ attribute

The special __slots__ class variable allows us to tell python which attributes the class will have. Python will then only allocate just enough memory to store these attributes, and trying to create any other attributes will cause an error:

class Point: 
    __slots__ = ('x', 'y')

    def __init__(self, x, y): 
        self.x = x
        self.y = y
>>> p = Point(1, 2)
>>> p.x
1
>>> p.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Point' object has no attribute '__dict__'
>>> p.z = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Point' object has no attribute 'z'

If a class uses __slots__, it's far more likely that all of its attributes are stored next to each other in memory. But it's still no guarantee. The python implementation can store the attributes however it wants.

like image 198
Aran-Fey Avatar answered Dec 25 '22 17:12

Aran-Fey


Not in general because the attributes of an ordinary object are stored in a hash table, keyed by the attribute name. Other implementations are possible (as in Self and some Javascript implementations), but to my knowledge, no Python implementation currently does this.

If you used tuples, as in collections.namedtuple (the implementation is quite instructive), then the pointers would be adjacent.

like image 35
Florian Weimer Avatar answered Dec 25 '22 16:12

Florian Weimer