Hey Python! Are you Call by Reference or Value?

When I started to learn computer science and programming, Call By Reference/value was one of the terminologies I kept hearing. Honestly, I did not take them that seriously (Yeah I know, shame on me). I was telling myself: ‘Who cares? when I need to do it, I will Google it!’

Time passed and a couple of years ago I was doing a job interview in Python. I was supposed to do something with a List. There was a function that pushed/popped/cleared elements based on a condition. Suddenly, I noticed I had one question I had no answer for: Should I pass the List in the main code thread to the function and then return the modified one?

Whoops! No idea!

Let me rephrase. Are functions in Python call-by-reference or value?

Reference (Pointer)

To answer the mentioned question, we need to understand what is a reference (pointer).

We all probably heard that Python is an Object Oriented Language. But what does it mean?

In Python, like many other languages, everything is an object. This means when we assign a value to a variable, the variable is a reference to that object, not the actual value. A reference is the memory address in the Python heap memory that the Python memory manager utilizes to get its value.

What is Heap memory? Heap memories are used by many languages including Python to dynamically (during runtime) allocate/deallocate memory for objects and variables. 

So if we define an integer, it would be like:

The objects in Python are two types in this regard:

  • Immutable
  • Mutable

Immutable are the objects that their value cannot change. In Python:

  • Integer
  • String
  • Float
  • Tuples
  • Bytes
  • Boolean

Are immutable. Basically all built-in/primitive data types. Everything else is mutable.

But what does it mean when we say the value cannot change?

When we say for instance integer is immutable, this means if we assign a new value, Python creates a new reference and does not change the existing one. Same as if we assign integer x to a new variable y.

So the changes in x do not affect y.

Now let’s assume x is a List and we do the above assignment. This time both x and y point to the same memory and same list.

This means that now when we change x, we also change y. Very important!

If you want to copy a refernce in Python and keep the original one, you can use the copy function
import copy
x=[1,2]
y = copy.copy(x)

So functions are call by value or functions?

I think at this point it becomes clear: Both.

It depends on the function parameter. If the parameter is immutable such as Integer, then it is called by value. Otherwise is call by reference.

Example for immutable (call by value)

def my_func_by_value(x):
    x += 1
    return True

x = 1
my_func_by_value(x)
print(x)
## x is still 1

Now, the example for call by function:

def my_func_by_ref(x):
    x.append(2)
    return True

x = [1]
my_func_by_ref(x)
print(x)
## x is now [1,2]

So if we get the concept, we do not have to memorize the answer.

The key is to understand how the Language manages different data types while copying/passing them.

The End.