DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 964,423 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Python’s Functions Are First-Class βš™οΈ
Mahmoud EL-kariouny
Mahmoud EL-kariouny

Posted on • Updated on

Python’s Functions Are First-Class βš™οΈ

Python has a feature that is unique among popular programming languages- its functions are first-class objects.

A function in Python is a special kind of object.

A function is an object with a name, that is callable like a method or a method's implementation in C++, Java, or C#.

Functions are functions like you are accustomed to in other languages. In Python, a function is just a function.

You can define a function anywhere in your Python program, just like any other object type, using the def keyword followed by the function name and a list of arguments in parentheses.

Code Example: 

def add(x, y): 
     return x + y  
Enter fullscreen mode Exit fullscreen mode

Python’s functions are first-class objects.

You can assign them to variables, store them in data structures, and pass them as arguments to other functions, and even return them as values from other functions.

def toy(text):
    return text.upper() + '!'

toy('hello')

HELLO!
Enter fullscreen mode Exit fullscreen mode

Functions Are Objects

All data in a Python program is represented by objects or relations between objects.

Things like strings, lists, modules, and functions
are all objects.

There’s nothing particularly special about functions in
Python. They’re also just objects.

Because the toy function is an object in Python, you can assign it to another variable,

just like any other object:

play = toy
Enter fullscreen mode Exit fullscreen mode

This line doesn’t call the function.

It takes the function object referenced
by toy and creates a second name, play, that points to it.

You could now also execute the same underlying function object by calling play:

def toy(text):
    return text.upper() + '!'

play = toy

play('toy story')

"TOY STORY!"
Enter fullscreen mode Exit fullscreen mode

What happens under the hood

Image description

Function objects and their names are two separate concerns.
Here’s more proof: You can delete the function’s original name toy.

Since another name play still points to the underlying function you can still call the function through it:

>>> del toy
>>> toy('hello?')

NameError: "name 'toy' is not defined"

>>> play('hey')
'HEY!'
Enter fullscreen mode Exit fullscreen mode

By the way, Python attaches a string identifier to every function at creation time for debugging purposes.

You can access this internal identifier with the name attribute:

>>> play.__name__
'toy'
Enter fullscreen mode Exit fullscreen mode

Now, while the function’s name is still toy that doesn’t affect how you can access the function object from your code.

The name identifier is merely a debugging aid.

A variable pointing to a function and the function itself are really two separate concerns.

Functions Can Be Stored in Data Structures

Since functions are first-class citizens, you can store them in data structures, just like you can with other objects.

For example, you can add functions to a list:

>>> funcs = [play, str.lower, str.capitalize]
>>> funcs
[<function toy at 0x10ff96510>,
<method 'lower' of 'str' objects>,
<method 'capitalize' of 'str' objects>]
Enter fullscreen mode Exit fullscreen mode

Accessing the function objects stored inside the list works like it would with any other type of object:

>>> for f in funcs:
       print(f, f('hey there'))
<function toy at 0x10ff96510> 'HEY THERE!'
<method 'lower' of 'str' objects> 'hey there'
<method 'capitalize' of 'str' objects> 'Hey there'
Enter fullscreen mode Exit fullscreen mode

You can even call a function object stored in the list without first assigning it to a variable.

You can do the lookup and then immediately call the resulting β€œdisembodied” function object within a single expression:

>>> funcs[0]('heyho')
'HEYHO!'
Enter fullscreen mode Exit fullscreen mode

Functions Can Be Passed to Other Functions

Because functions are objects, you can pass them as arguments to
other functions.

Here’s a greet function that formats a greeting string
using the function object passed to it and then prints it:

def greet(func):
    greeting = func('Hi, I am a Python program')
    print(greeting)
Enter fullscreen mode Exit fullscreen mode

You can influence the resulting greeting by passing in different functions. Here’s what happens if you pass the paly function to greet:

>>> greet(play)
'HI, I AM A PYTHON!'
Enter fullscreen mode Exit fullscreen mode

Of course, you could also define a new function to generate a different flavor of greeting.

For example, the following whisper function might work better if you don’t want your Python programs to sound like Optimus Prime:

def whisper(text):
     return text.lower() + '...'

>>> greet(whisper)

'hi, i am a python program...'
Enter fullscreen mode Exit fullscreen mode

The ability to pass function objects as arguments to other functions is powerful.

It allows you to abstract away and pass around behavior in
your programs.

In this example, the greet function stays the same but
you can influence its output by passing in different greeting behaviors.

Functions that can accept other functions as arguments are also called higher-order functions.

They are a necessity for the functional programming
style.

The classical example for higher-order functions in Python is the built-in map function.

It takes a function object and an iterable, and then
calls the function on each element in the iterable, yielding the results as it goes along.

Here’s how you might format a sequence of greetings all at once by
mapping the play function to them:

>>> list(map(play, ['hello', 'hey', 'hi']))
['HELLO!', 'HEY!', 'HI!']
Enter fullscreen mode Exit fullscreen mode

As you saw, map went through the entire list and applied the paly function to each element.

As a result, we now have a new list object with
modified greeting strings.

Connect with Me 😊

Top comments (0)

πŸŒ–πŸŒ—πŸŒ˜ Turn on dark mode in Settings