Python Functions as Arguments: A Beginner’s Guide

Have you ever wondered if you could use a function as a variable in Python? What if you could send one function into another, just like you would with a number or a string? This might sound like an advanced concept, but it’s a fundamental and powerful feature of Python that unlocks a world of flexibility.

In this guide, we’re going to demystify one of Python’s core concepts: treating functions as first-class objects. By the end of this post, you’ll understand exactly what it means to pass a function as an argument to another function, and you’ll be able to do it yourself with confidence.

What Are First-Class Functions?

In Python, functions are first-class citizens. This is a fancy term that means functions can be treated just like any other data type, such as integers, strings, or lists.

Specifically, this means you can:

  1. Assign a function to a variable.
  2. Store a function in a data structure (like a list or dictionary).
  3. Pass a function as an argument to another function.
  4. Return a function from another function.

Today, we’re focusing on the third point: passing functions as arguments. This is a cornerstone of functional programming in Python and is used extensively in popular libraries.

Passing a Function as an Argument: A Step-by-Step Walkthrough

Let’s break this down with a simple, clear example. We’ll create two functions and then pass one into the other.

Step 1: Define Our Functions

First, we’ll create a simple function called greet() that prints “Hello”.

def greet():
    print("Hello")

Next, we’ll create another function called world(). This function will take a single parameter, which we’ll call func. Inside, it will simply print “world”.

def world(func):
    print("world")

At this point, these are two independent functions. Now, let’s connect them.

Step 2: Passing the Function

The magic happens when we call the world() function. Instead of passing a string or a number, we’re going to pass the greet function itself.

Crucially, notice we write greet without the parentheses ().

  • greet() calls the function and uses its return value (which is None in this case).
  • greet refers to the function object itself, which we can pass around.
# This passes the 'greet' function object into 'world'
world(greet)

When this line runs, the greet function object is passed to world and assigned to its parameter, func. So, inside the world function, func now is the greet function.

Step 3: The Complete Working Code

Let’s put it all together and enhance our world function to actually use the argument it receives.

def greet():
    print("Hello")

def world(func):
    # Let's check the type and ID of 'func'
    print(f"The type of 'func' is: {type(func)}")
    print(f"The id of 'func' is: {id(func)}")
    
    # Now, let's call the function that was passed in!
    func()  # This is the same as calling greet()
    
    print("world")

# Pass the 'greet' function object to 'world'
world(greet)

When you run this code, you’ll see the following output:

The type of 'func' is: <class 'function'>
The id of 'func' is: 140736198743040
Hello
world

Let’s analyze the output:

  • The type of 'func' is: <class 'function'>: This confirms that func inside world is indeed a function object.
  • The id of 'func' is: ...: This shows the memory address where the function object lives.
  • Hello: This is printed when we call func(), which executes the greet function.
  • world: This is the final line printed by the world function itself.

Understanding the “Why”: Python’s Object Model

To truly grasp what’s happening, remember how Python variables work. Think of a variable as a tag attached to an object.

When we define def greet(): ..., Python creates a function object in memory and attaches the tag greet to it.

When we call world(greet), we are essentially creating a new tag, func (the parameter inside world), and attaching it to the exact same function object.

We can prove this by comparing their memory addresses.

def greet():
    print("Hello")

def world(func):
    print(f"ID of 'func': {id(func)}")
    print(f"ID of 'greet': {id(greet)}")
    print(f"Are they the same object? {func is greet}")

world(greet)

Output:

ID of 'func': 140736198743040
ID of 'greet': 140736198743040
Are they the same object? True

This confirms that both greet and the inner func are pointing to the same underlying object. There’s no duplication; it’s just two names for the same function.

Why Is This Useful? Real-World Applications

You might be thinking, “This is neat, but when would I actually use it?” This pattern is incredibly common. For example, the built-in sorted() function uses it.

The key parameter in sorted() lets you pass a function that determines how items are sorted.

# A list of names we want to sort case-insensitively
names = ['Alice', 'bob', 'Charlie', 'dave']

# We pass the 'str.lower' function as an argument to sorted.
# This tells sorted to convert each string to lowercase before comparing them.
sorted_names = sorted(names, key=str.lower)

print(sorted_names)
# Output: ['Alice', 'bob', 'Charlie', 'dave'] (now correctly sorted)

In this example, we didn’t call str.lower() ourselves. We passed the function str.lower to sorted, and sorted called it for each item internally. This is the power of passing functions as arguments!

Ready to Go from Basics to Pro?

Mastering concepts like first-class functions is what separates novice Python programmers from proficient ones. It opens the door to powerful programming paradigms and allows you to write cleaner, more efficient, and more expressive code.

If you’re serious about mastering Python, check out our pre-recorded python comprehensive video course.

Conclusion

Congratulations! You’ve just unlocked a key Python superpower. You now understand that functions in Python are first-class objects, which means you can pass them as arguments to other functions. You learned this by walking through a practical example, saw how to verify the object’s type and identity, and even glimpsed a real-world use case with the sorted() function. This is a huge step forward in your Python journey.

Keep practicing by trying to pass your own custom functions to sorted or map. The more you play with it, the more intuitive it will become.

Common Questions About Python Functions as Arguments

Q: What’s the difference between greet and greet()?
A: greet refers to the function object itself. greet() is a function call that executes the function’s code and evaluates to its return value (e.g., None for a simple print function).

Q: Can I pass a function with arguments?
A: Not directly in this way. To pass a function that requires arguments, you would often use a wrapper function or lambda functions. For example: my_list.sort(key=lambda x: x[1]) passes an anonymous function that takes an argument x.

Q: Is this the same as a callback function?
A: Yes, exactly! When you pass a function as an argument to be called later by the receiving function, the passed function is often called a “callback.