Skip to content
Home » Functions as First-Class Objects

Functions as First-Class Objects

Spread the love

Today we’ll be talking about functions in Python. Functions in Python are often described as first-class objects. It just means they are objects no less than integers, strings or our custom objects created by instantiating classes. In particular it means, functions may be used just like the other objects: they can be assigned to variables, they can be passed as arguments to other functions and they can be returned from other functions.

first-class objects

Let’s have a look at each of these cases one by one.

Functions Assigned to Variables

First, let’s see how functions may be assigned to variables:

Here’s a simple function that prints a character in rows and columns:

>>> def dense_repeat(character, rows, columns):
...     for row in range(rows):
...         for column in range(columns):
...             print(f" {character} ", end = "")
...         print()
...

Let’s call it to see how it works:

>>> dense_repeat ("X", 4, 6)
 X  X  X  X  X  X 
 X  X  X  X  X  X 
 X  X  X  X  X  X 
 X  X  X  X  X  X 

Now let’s assign the function to a variable:

>>> a = dense_repeat

Now we can use the variable as the function:

>>> a("+", 8, 15)
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 

Functions Passed As Arguments to Functions

OK, the next thing we can do is pass a function as an argument to another function. Here’s the function we used before:

def dense_repeat(character, rows, columns):
    for row in range(rows):
        for column in range(columns):
            print(f" {character} ", end = "")
        print()

Here’s a similar function. It just adds more spaces around the characters:

def scarce_repeat(character, rows, columns):
    for row in range(rows):
        for column in range(columns):
            print(f"  {character}  ", end = "")
        print("\n")

Your Panda3D Magazine

Make Awesome Games and Other 3D Apps

with Panda3D and Blender using Python.

Cool stuff, easy to follow articles.

Get the magazine here (PDF).

Now let’s create another function. It will take a function as an argument and call it:

def repeat(func, character, rows, columns):
    # We can use the __name__ attribute on the function object
    # to retrieve the function's name.
    print(f"using the {func.__name__} function:")
    func(character, rows, columns)

Now let’s use our repeat function twice. We’ll pass the dense_repeat function first and then the scarce_repeat function. The other arguments are the same so that it’s easier to compare how the two functions work:

repeat(dense_repeat, "X", 6, 8)
repeat(scarce_repeat, "X", 6, 8)

And here is the output:

using the dense_repeat function:
 X  X  X  X  X  X  X  X
 X  X  X  X  X  X  X  X
 X  X  X  X  X  X  X  X
 X  X  X  X  X  X  X  X
 X  X  X  X  X  X  X  X
 X  X  X  X  X  X  X  X
using the scarce_repeat function:
  X    X    X    X    X    X    X    X

  X    X    X    X    X    X    X    X

  X    X    X    X    X    X    X    X

  X    X    X    X    X    X    X    X

  X    X    X    X    X    X    X    X

  X    X    X    X    X    X    X    X

Python Jumpstart Course

Learn the basics of Python, including OOP.

with lots of exercises, easy to follow

The course is available on Udemy.

Functions Returned from Functions

Finally, let’s see how functions may be returned from other functions:

Let’s modify the dense_repeat function so that it returns a function:

def dense_repeat(character):
    def layout(rows, columns):
        for row in range(rows):
            for column in range(columns):
                print(f" {character} ", end = "")
            print()
    # Now the dense_repeat function returns the layout function.
    return layout

# If we now assign the result returned from the dense_repeat function
# to a variable, what we actually assign is the layout function.
star_pattern = dense_repeat("*")

# Now we can use star_pattern as the layout function. What's interesting,
# it still remembers the character to print, although the enclosing 
# dense_repeat function has already returned. We call such functions 
# closures.
star_pattern(10, 8)

If you want to learn more about closures, I have an article about them, so feel free to read it.

And here’s the output:

 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *

As you can see, you can use functions just like any other objects. This makes them first-class objects.

Blender Jumpstart Course

Learn the basics of 3D modeling in Blender.

step-by-step, easy to follow, visually rich

The course is available on Udemy and on Skillshare.

Here’s the video version of this article:


Spread the love

Leave a Reply