First-Class Functions in Python
Exprimenting with Functions that can be treated like any other value in Python
First-Class Functions
First-class functions are functions that can be treated like any other value. You can pass them to functions as arguments, return them from functions, and save them in variables.
Properties of first class functions:
- A function is an instance of the Object type.
- You can store the function in a variable.
- You can pass the function as a parameter to another function.
- You can return the function from a function.
- You can store them in data structures such as hash tables, lists, …
# Python program to illustrate functions
# can be treated as objects
def shout(text):
return text.upper()
print(shout('Hello'))
yell = shout
print(yell('Hello'))
Functions can be passed as arguments to other functions:
Because functions are objects we can pass them as arguments to other functions. Functions that can accept other functions as arguments are also called higher-order functions. In the example below, we have created a function greet which takes a function as an argument.
# Python program to illustrate functions
# can be passed as arguments to other functions
def shout(text):
return text.upper()
def whisper(text):
return text.lower()
def greet(func):
# storing the function in a variable
greeting = func("Hi, I am created by a function passed as an argument.")
print(greeting)
greet(shout)
greet(whisper)
Let's look an other example on passing a function as an argument to another function. A great example of this is the Map
function.
Map Function takes a function and an array as its arguments and it runs each value of that array through the provided function and then returns a new array of those results.
def my_map(func, arg_list):
result = []
for i in arg_list:
result.append(func(i))
return result
def square(x):
return x*x
def cube(x):
return x*x*x
squares = my_map(square, [1, 2, 3, 4, 5])
# We are not adding the parentheses for square function
# Because adding parentheses would try to execute the function
print(squares)
cubes = my_map(cube, [1, 2, 3, 4, 5, 6])
print(cubes)
# Python program to illustrate functions
# Functions can return another function
def create_adder(x):
def adder(y):
return x+y
return adder
add_15 = create_adder(15)
print(add_15(10))
def logger(msg):
def log_message():
print('Log: ', msg)
return log_message
log_error = logger("Fatal, error")
log_error()
logger("Info: Hello")()
Using Return Insted of Print
def rt_logger(msg):
def rt_log_message():
return 'Log: ', msg
return rt_log_message
rt_logger("hii")
# As we are returning a function with out parentheses, it won't be able to execute
# unless the parentheses are given and called
rt_logger("hii")()
# Returning a executing function
def rt_logger(msg):
def rt_log_message():
return 'Log: ', msg
return rt_log_message()
rt_logger("hii")
def logger_wth_args(msg):
def log_message_args(log_arg):
print("Outer Fucntion Log value: ",msg)
print("Inner Function Log value: ", log_arg)
print("Together: ",msg,log_arg)
return log_message_args
lgr = logger_wth_args("Info:")
lgr("LGR Var created")
lgr("No Var created")
One thing important to point out here is that from the first step when we gave Info:
as an argument for logger_wth_args()
and till the last step when we gave No var created
as an argument for returned function log_message_args
. It remembered our initial message that we passed in to this initial logger funciton [Outer function]. This what called as a Closure.
def html_tag(tag):
def wrap_text(msg):
print('<{0}>{1}</{0}>'.format(tag, msg))
return wrap_text
print_h1 = html_tag('h1')
print_h1('Test Headline!')
print_h1('Another Headline!')
print_p = html_tag('p')
print_p('Test Paragraph!')