Blog Post #85: The Anatomy of a Function Call

In Post #84, we learned how to define a function with def and then use it by “calling” it. We established that defining a function is like writing a recipe, and calling it is like cooking the dish. This distinction is one of the most important concepts when working with functions.

In this post, we’re going to zoom in on the “call” itself. We’ll dissect its syntax, clarify some important terminology, and understand exactly what happens when you execute a function.

Definition vs. Call: A Quick Review

Let’s quickly review the two distinct states of a function.

  • The Definition: This is the block of code that starts with def. It’s the blueprint for a task. The code inside is not executed when Python reads the definition; it’s simply stored in memory for later use.
  • The Call (or Invocation): This is the act of telling Python to run the code inside the function’s body. The terms “calling a function” and “invoking a function” mean the exact same thing.

The Key Ingredient: Parentheses ()

The syntax for calling a function is simple: its name followed by parentheses.

my_function_name()

The parentheses () are the call operator. They are the critical signal that tells Python, “Don’t just look at this function, I want you to run it now!”

To prove this, let’s see what happens when we refer to a function’s name with and without the parentheses.

def say_hello():
    print("This function is now running!")

# Case 1: Referencing the function object (no parentheses)
print("--- Without parentheses ---")
print(say_hello)

# Case 2: Calling the function (with parentheses)
print("\n--- With parentheses ---")
say_hello()

The output of this code will be something like this:

--- Without parentheses ---
<function say_hello at 0x000001A8D49A3C20>

--- With parentheses ---
This function is now running!

In the first case, Python simply tells us what say_hello is: a function object stored at a specific location in memory. We are referring to the recipe itself. In the second case, the parentheses () tell Python to execute the code inside the function, and our message is printed.

The Flow of Execution

When you call a function, you are temporarily redirecting the flow of your program. Here’s what happens, step-by-step:

  1. Your program runs top-to-bottom until it hits a function call.
  2. The program’s execution jumps to the first line inside that function’s def block.
  3. It runs all the code inside the function’s body from top to bottom.
  4. Once the function body is complete, execution returns to the point it left off, right after the original function call.

Let’s trace this flow:

def simple_function():
    print("  --> Now inside the function.")

print("Program starts here.")
simple_function() # Execution jumps to the function
print("Program has returned from the function.")

The output will perfectly match the flow of execution:

Program starts here.
  --> Now inside the function.
Program has returned from the function.

What’s Next?

You now know the crucial difference between a function definition and a function call. A function call is an action, triggered by the () operator, that causes the program’s execution to jump into the function’s body and then return. Understanding this flow and terminology is key to writing and debugging more complex programs.

Our functions so far have been simple; they do the same thing every time. To make them truly powerful and flexible, we need a way to pass information into them when we call them. In Post #86, we will learn how to do this by exploring the difference between parameters and arguments.

Author

Debjeet Bhowmik

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com

Leave a Comment