Syed Jafer K

Its all about Trade-Offs

Python Variable – Is a Container or a Reference ?

Unlike other programming languages, in Python, variable is not a container but just a reference or a name/label to the object.

Caution: This post deals with memory management, which might confuse you if you are a beginner. Read at your own risk.

Let’s dive deep into it,

To understand how python handles variable storage and references involves several key concepts,

Objects & References:

In python, everything is an object and variables are references to these objects. To check if an item is an object, we can use the isinstance() function.

This will give,

Now we can see that everything in python is an object.

Let’s try to prove,

When you create a variable (label), it holds a reference (a pointer) to the memory location where the actual object is stored.

To validate this we need to check the size of the objects and the address of the objects. We can use

  • id() function to check the address of the object
  • getsizeof() method from sys module to find the size of the object.

Let us take an example,


age = 26 

26 is the Numeric object which is stored in some memory address.

import sys

age = 26
print("Address of 26 (Numeric Object)", id(26))
print("Address of age", id(age))
print("Size of reference:", sys.getsizeof(x))  # Size of the reference

Here we can see the address of both the age and 26 are same. Its because the numeric object 26 is stored in the memory address (140593168368656) and its been referenced to age.

Okay, So where does the variable gets stored,

Python maintains namespaces, which are dictionaries that map variable names to objects. The process of associating a variable name with an object is called binding. When you assign a value to a variable, you are binding the variable name to an object in the namespace.

Variable names are stored in namespaces (which are dictionaries).

For example,

  • local variables are stored in a dictionary specific to the function
  • global variables are stored in the module’s dictionary, and so on.

import sys

x = 10
print("Size of reference:", sys.getsizeof(x))  # Size of the reference
local_namespace = locals()
print("Namespace:", local_namespace)  # Shows the local namespace
for key, value in local_namespace.items():
  print(key, value)

In the above code, we can see the variable x is stored in the namespace, which is a reference to the object 10. Both x and 10 will have the same address.

So, now we can say that variables in python is not a container but a label to the object.

So now what is the size of an variable ?

In Python, you can get the size of the reference (pointer) itself using the sys.getsizeof() function. However, sys.getsizeof() typically returns the size of the object that the reference points to, not the size of the reference itself.

Python does not provide a direct way to get the size of just the reference (pointer). This is because Python abstracts away the details of memory management and does not expose low-level details like the size of pointers directly to the user.

The size of a reference (pointer) is typically determined by the architecture of the system (e.g., 4 bytes on a 32-bit system, 8 bytes on a 64-bit system).

But we can try to get a rough estimate of the size,

import sys

def get_reference_size():
    # Create an object and get its size
    obj = 123
    
    # Create a list to hold references to the object
    reference_list = [obj] * 1000
    
    # Get the size of the list with references
    size_of_reference_list = sys.getsizeof(reference_list)
    print("size_of_reference_list", size_of_reference_list)
    
    # Calculate the size of one reference
    size_of_empty_list = sys.getsizeof([])
    size_of_one_reference = (size_of_reference_list - size_of_empty_list) / 1000
    
    return size_of_one_reference

print("Estimated size of one reference (pointer):", get_reference_size(), "bytes")

In the above code, we created a list of 1000 values (i.e 1000 times 123).

As per documentation,

Some objects contain references to other objects; these are called containers. Examples of containers are tuples, lists and dictionaries. https://docs.python.org/3/reference/datamodel.html

So the list object contains the reference to the other objects. So here it contains 1000 references to the value 123.

And then we are trying to calculate the size of the list of references and then dividing by the total number to get the size of the singe reference (or pointer or label).

Now, the size of a single variable it 8 bytes (Note: It depends on the system architecture.)

Inference:

  • Variables are not the containers.
  • Variables are just the labels to the objects. Variables and the variable name are same.
  • There is no type for the variables. If we use type(variable) it gives the type of the object which it refers to.
  • Variables are stored in the namespace.
  • Variables are having the size which varies based on the architecture. It might be 4 bytes or 8 bytes.