Functions in Python

Functions in Python

11 mins read1.3K Views Comment
Updated on Aug 27, 2024 17:25 IST

By Varun Dwarki

2021_12_Untitled-design.jpg

 

Python is the preferred choice of programming language for developers, data scientists, engineers, and programming enthusiasts everywhere. You can use it for simple scripting to build sophisticated web applications. This article will help you get acquainted with the nuances of Functions in Python and how to effectively take advantage of them.

The topics that you will learn in this article are:

  1. What are Functions in Python
  2. Why Use Functions?
  3. Coding Functions
    1. Defining Functions
    2. Specifying Function Docstring
  4. Python Namespace and Scope
    1. Local Variables
    2. The global Statement
  5. Argument Passing in Python
    1. Types of Python Arguments
  6. Return Values
  7. Conclusion

What are Functions?

Functions are a simple way to decompose a complex large problem into intellectually manageable chunks. In technical terms, a function is a set of statements or instructions that perform a certain task, grouped together as a unit, so they can be run more than once in a program.

 

2021_12_Functions-in-Python-1.jpg

 

If you ignore the code for now (which will be covered later), you can see that a function is simply a block of instructions, packaged as a unit, just like a box. This sort of practice allows us to write code that is both reusable and easier.

Before we get into the technical details, let us establish a clear picture of why functions are important.

Recommended online courses

Best-suited Python for data science courses for you

Learn Python for data science with these high-rated online courses

Free
4 weeks
12 K
8 hours
4.24 K
6 weeks
40 K
100 hours
4.99 K
– / –
– / –
– / –
– / –
60 hours
– / –
90 hours
1.26 L
12 hours

Why Use Functions in Python?

Functions are a universal programming structure and a very important content in any programming language. Listed below are a few reasons why we need them,

Reduce Code Duplication: Functions are the simplest way to package your code to use it at multiple places at multiple times

Procedural Decomposition: Functions are a tool for splitting a complex system into well-defined, meaningful, intellectual pieces. For instance, you can divide your “make a pizza” task into smaller chunks such as mixing the dough, rolling it out, baking it, and so on

Hide Implementation Details: Just by looking at the function name, you can pretty much understand the purpose of the function. You are not forced to delve into implementation details

Now that you are aware of what functions are and why they are important, let us explore the tools used to code functions in Python.

Coding Functions

You might have probably come across or used some functions in your course of programming journey. For instance, you might have to use a built-in int function to create an integer object, or len built-in function to find the number of items in a sequence object, and so many others. These are nothing but the built-in functions that Python offers to a user. Each of these functions performs a single, well-defined task.

To use these functions, all you have to know is its name, purpose, the arguments it takes, and the values it returns. That is unless you want to create a new function on your own. We call them custom functions. In this article, we will explore how to define and call custom functions. These functions behave the same way as the normal built-in functions except for a few additional details that you might have to keep in mind when working with them.

Defining Functions

Functions in Python are defined using the keyword def, followed by the name of the function, terminated by a pair of braces (which may or may not have input parameters, and at last, a colon ( : ). Here’s a simple example of a function square, that calculates the square of its argument, when called.

#Example 1

def square(num):

“””Calculate the square of number.”””

return num ** 2

square(2.5)

You should know that, unlike functions in compiled languages such as C, in Python def is an executable code. By that I mean, that function that you define does not exist until Python reaches and runs the def. When Python runs a def statement, it creates an object and assigns a name to it.

In the above example, the function name is “square”. The def statement just defines the function but does not call. Once the function is defined, you can call (run) the function in your program by using the function name, followed by parenthesis (parameters if any). From the above example, we have

square(2.5)# Arguments in parentheses

Function objects may also have an arbitrary list of parameters representing the data on which the function has to perform its task. The square function has a single parameter named num, the data value that has to be squared. Post the colon ( : ), the indented lines are the function’s block, the set of instructions that perform the function’s task.

Once the function finishes the execution, the control is returned to its caller, i.e. the line of code that has called the function. In the example above, the return statement first squares the number num, then terminates the function, and returns back the control to the caller.

Specifying Function Docstring

Let us consider an example: Calculating the factorial of a given number.

#Example 2

def factorial(n):

“””Returns factorial of a number.”””

= 1

return m if n < 2 else n * factorial(n-1)

print(factorial(5))
print(type(factorial))
print(help(factorial))
factorial.__doc__

The functions that are used in real-life applications are often complex, in the sense, it might take time to go through the entire code to figure out its purpose. Wouldn’t it be nice if there is a brief description that explains the function’s purpose? That’s exactly why it is suggested to have the first line in a function’s block as docstring that explains the purpose. In the above example, we have:

“””Returns factorial of a number.”””

One of the function attributes __doc__ , is used to generate the help text of a Python object. You can print a function’s docstring (nicely formatted one) using help()function. If you are just interested in the raw docstring without any formatting, you can use the __doc__ function.

Another interesting thing in the above example is the variable m inside the factorial function. It is called a local variable and is visible only to lines of code inside the function defined. So, what do I mean by that?

Check out top python interview questions 

Python Scopes

Now that you are ready to build your own functions, you should know how Python deals with the names that you use in your code. Let’s say you are looking for a book, so you go to the library and ask the librarian about the location of the book. The librarian tells you something like, “Third floor, section C, row 5”. So, there you go in search of your book much more easily.

Similarly, Python tries to keep your code organised by using the concept of namespace – a place where names live. Since names are not declared ahead of time, Python uses the location in your code where you have defined the name, to determine the scope of the name’s visibility in the code. To make this easier to understand, let us consider a simple example.

#Example 3

import math    #global scope

= math.pi

def area(r):

= X * r * r      # r and Z: local scope

return Z

area(2)

In the above example, the scope of variable X is global, which is to say that X is assigned at the top level of the enclosing module file and is just referenced by the function area. Likewise, the variables r and Z are local variables.

They are local to the function area (in our example) and they serve as temporary names that you need only while a function is running. By default, all the names that are assigned within a function definition belong to the local scope. Now, what if you want to change the value of the variable X inside the function? How can you achieve that?

The global Statement

You can use global statements to change one or more global names (the names that live outside a def statement at the top level) inside your function.

#Example 4

var = 99                #global variable

def local1():

var = 88

print(var)      #local variable with the same name as global variable

def global1():

global var

var = 77

print(var)  #using global statement

print(var)

local1(); global1()

In the above example, we were successfully able to change the value of global variable X inside the function global1 using the keyword global. You will also notice that names that are assigned inside a def do not clash with variables assigned outside the def, even when you use the same names.

Note: It’s suggested to minimise the use of global variables unless you cannot avoid using them. Variables inside def are local for a reason and changing global variables can make your code complex, difficult to understand and debug.

Check out Python Based online Courses

Passing Arguments

Now let us explore the powerful syntax that Python offers to declare function parameters and how to pass arguments into them. Before we jump in here are some simple points regarding argument passing that you should remember:

  • Passing arguments to a function is nothing but assigning objects to local variable names
  • Within the scope of the function, assignment to argument names does not affect the caller

#Example 5

def func(A):

= 10     # we are defining local A, not changing the global one

= 3

func(A)

print(A)

  • Modifying the passed-in mutable objects in place may affect the caller

#Example 6

def func(X, Y):

= 10      # we are defining local A, not changing the global one

Y[1= ‘Jim’ # Y is mutable object. This affects the caller

= 3

= [1, 2, 3]

func(X, Y)

print(“The value of X after the function call:”, X)

print(“The value of Y after the function call:”, Y)

Types of Arguments

There are xxx ways of specifying arguments. Let us explore each of these in brief.

Positional Arguments

Positional arguments are the basic type of arguments where the passed argument values are matched to argument names in the function header from left to right.

#Example 7

def area_rectangle(l, b, w):

area1 = l * b * w

return area1

print(area_rectangle(5, 4, 8))

Keyword Arguments and Default Values

Functions in Python can also be called using keyword arguments, where the caller can specify which argument name in the function header is to receive the value by using the argument name in the function call. Let us now modify the above example using the keyword arguments.

#Example 8

def area_rectangle(length, breadth, width):

area1 = length * breadth * width

return area1

print(area_rectangle(width = 8, length = 5, breadth = 4))

Note that each keyword argument in a call has the form name=value. Since keyword arguments are matched by name, their order doesn’t matter. In the above example, the function call passes the arguments in the order width, length, and breadth. Whereas in the function header the parameters are in the order length, breadth, and width. Please note that this might have limitations when you are passing arguments of different types.

Explore Free Online Courses with Certificates

Default Argument Values

Python allows you to specify a default value for one or more arguments to receive if the function call passes too few values. Even here, it uses the name=value syntax.

#Example 9

def area_rectangle1(length, breadth = 7, width = 2):

area1 = length * breadth * width

return area1

#keyword arguments

print(area_rectangle1(width = 8, length = 5, breadth = 4))

#default argument values: length=5, breadth=7, width=2  

print(area_rectangle1(length = 5))

#keyword arguments after positional arguments                           

print(area_rectangle1(1))

print(area_rectangle1(11, 12, 13))

print(area_rectangle1(10, breadth = 10))

From the above examples the important points that you can infer are as follows:

  • Default argument allows you to create a function that can be called with fewer arguments
  • They are calculated when the function is defined, not when it is run
  • You cannot specify a default argument on the left of the positional argument
  • In a function call, you should always place keyword arguments after positional arguments. Doing so will give you an error saying “SyntaxError: positional argument follows keyword argument

#Example 10

def area_rectangle12(length, breadth = 7, width = 2):

area1 = length * breadth * width

return area1

print(area_rectangle(length = 4, 42))

Variable Arguments

Python allows you to define a function that can receive any number of arguments by using one or more *characters. Do not confuse it with the pointers like in C language. Python doesn’t have the concept of pointers!

Let’s try to understand with the help of an example: Gathering variable positional arguments with *

#Example 11

def stud_details(*args):

print(“Student Details (Variable Positional Arguments):”, args)

def stud_details1(id, name, *args):

print(“Required Positional Arguments:”, id, name)

print(“Rest of the Positional Arguments:”, args)

stud_details(“1JS13CS028”, “Jim”, 25, “Computer Science”, ‘and….’)

stud_details1(“1JS13CS027”, “Sam”, 25, “Computer Science”, ‘other details…’)

The * operator groups multiple positional arguments into a tuple of parameter values, according to how the function is called. Similarly, you can do the same for keyword arguments using two asterisks (**).

#Example 12

def print_kwargs(**kwargs):

print(kwargs)

print_kwargs(id=1, age=22)

print_kwargs(**{‘id’1, ‘age’22})

print_kwargs(**dict(id=1, age=42))

You can use two asterisks (**) to group a variable number of keyword arguments into a dictionary, where the argument names in the function call are keys, and the values of those arguments are corresponding dictionary values. Apart from these, I suggest you explore positional-only arguments, keyword-only arguments, and both of them combined.

Just one more thing about passing arguments to functions. So, in Python do we pass arguments using pass-by-value or pass-by-reference? In Python, the arguments are always passed by reference or often referred to as pass-by-object, because pretty much everything in Python is an object.

Explore Popular Online Courses

Function Returning Values

We have briefly discussed how the function returns values in the earlier section. In Python, a function uses a return function to send back a result object to the caller. A function always returns something, even when function return() is not explicitly called.

In this case, it just returns None object, the default result. There is another advanced way of returning results, which is using the yield function and you should definitely check that out.

That’s it, folks! With this, we have reached the end of the article. Functions are a very basic and important topic of every programming language, including Python. Master them and you will know how to code smartly by reusing the code.

________________

If you have recently completed a professional course/certification, click here to submit a review.

About the Author

This is a collection of insightful articles from domain experts in the fields of Cloud Computing, DevOps, AWS, Data Science, Machine Learning, AI, and Natural Language Processing. The range of topics caters to upski... Read Full Bio