How Do Functions Work in Python?

How do functions work in Python

Understanding how functions work in Python is key to building clean and reusable code in your programs. In addition, understanding how Python functions work will help when working with a framework like Django or Flask which are both written in the Python programming language. In fact, this is probably one of the key benefits, since you will be able to scan source files and look at various function definitions to understand what the software offers you. Recall that in general terms and regardless of the programming language, a function serves the purpose of reducing code duplication, breaking down larger problems in to smaller ones, increasing readability of software, boosting code reuse, and information hiding.

First Class Citizens

You may have heard of the term “first class citizen” in programming circles before. Indeed the idea of functions as first class citizens is popular in the JavaScript world. What we mean when we say first class citizen is that functions are on the same level so to speak as other objects in the language. As a result of this, you can assign functions to variables or even pass them as an argument to other functions. Just like in JavaScript, this helps to allow one to bend the language to their will. Just like PHP has many functions that ship as part of the language, so too does Python. These are the built in functions and include functions such as abs(), dir(), bin(), len(), and many more. If you want to create your own function, you can do so by making use of the def keyword, and we will take a look at this next.

Creating A Python Function

The best way to learn is by doing. Therefore, let us try to create our very own function in Python and learn about what makes one, well, function. So let’s consider creating a function that adds two numbers together and returns the sum. Yes, consider it the “Hello World” of creating a function. On second thought, let’s actually start with the “Hello World” function since it doesn’t even need to accept any parameters and the adding function will.

Whoa. We got carried away there – I guess Adele has quite the far reaching influence these days. In any event, we can see just how we constructed this first function. Note that we start the function definition with the def keyword. If you even opened up a .py file from a popular Python software repository and noticed untold numbers of that keyword, now you know what it is for. It is for defining your functions. Right after the def keyword, we assign a name to identify the function followed by opening and closing parenthesis just like you might find in another programming language. After this, we find the colon : character. This indicates the beginning of the function code block which will house the logic that will get executed when a call is made to this function at a later time. The next few lines look simple, but they are important! In Python Whitespace means something! Before each call to print() there is exactly four blank whitespaces. If you get your whitespacing wrong in Python, the compiler will throw an error. This is a bit of a controversial aspect of Python, but if you want to program in this language – you will need to get used to it. After we define the function, we make a call to it by simply typing hello() on it’s own line with no spaces. We can see from the output, that we may have a future in the music business.

Next up, let’s create that adding function.

This function works just as we expect it might. Notice that in the definition of the function, we make an allowance for two parameters. These represent the two numbers we will pass to our function that it will add together. Then, we simply return the result of the first variable plus the second variable, represented by return one + two. The program output shows us that it is working like a charm. Let’s modify our function to accept user input, as it will be more flexible this way.

In running this iteration of the adding function, we can see from the program output that the user was prompted for the numbers to add. Something to note, is that the built in input() function is typically going to read data in as a string. This is why we need to wrap the call to input() by an int() call. This converts or casts the input data to an integer. This way, the adding happens in the numeric sense and not the string sense. Let’s see what happens if we do not include this call to int().

As we can see, that is probably not the result we are looking for!

Python Syntax

Now that we have a few working functions to look at, we can see what the general syntax looks like. It follows this outline as we have demonstrated.

The function can accept none, one, or many parameters. As we have seen the body of the function has no curly braces as delimiters. The body simply makes use of indentation as part of it’s definition. If there are required parameters, those are designated first. Optional parameters always come after required parameters. Within the statements of the function, one can make use of the return keyword to send the result of the function back to the calling location. When you use a return statement, it terminates the function call. There may be times when you do not need to return a value, but simply stop the execution of the function. In this case if you use return, it will simply return the None value. This equates to something like null in other languages.

Specifying Optional Parameters

Maybe you don’t like saying Hello to World. Perhaps you would like to choose who you are saying Hello to. We can do this with optional parameters.

In this iteration of the hello() function, we make the second portion of the hello message optional. We know it is optional because in the parameter definition itself, we assign the string of ‘World’ to the world parameter. What this says is, when you call the hello() function, if no argument is passed in, the world variable will be automatically assigned the value of ‘World’. If a value is passed in as an argument, it will overwrite this default value. We see this in action by saying hello to Jackson, J Lo, and Rico.

Adding a Docstring to a Python Function

In one of our prior tutorials, we had a cool little alphabet sorting example. In this iteration, we will turn it into a function, which of course makes the code reusable, while also adding a Docstring, which is almost a form of documentation for explaining what a function actually does. It follows the format of function_name.__doc__ and we will see an example here now.

How to return more than one value

We have seen that we can return a value from a function. There are times you want to return many values from a function however. Although you can not explicitly return several different variables representing different values, you can return a list or dictionary which holds the multiple values you wish to return. We see this all the time in other languages by returning an array of values, or an object that has many values. In Python, if you had to return 5 different integer values, you could return a tuple or list which contains these values and access them that way. Let’s have a look at a program that uses a multi value return now.

This example is pretty cool! First, we define a function that takes two parameters which are integers, and calculates the sum, modulo, and product of those two integers. Now, our goal is to return all of those resulting values out of the function. We can’t do something like return sum, return modulo, return product all in a row – the program will not work. So how do we make this work? The tuple comes to the rescue! Instead of trying to return each value on it’s own, we return one tuple. Within that tuple we have the result of each calculation. With this approach, we get to access all three values when we call the function in the while loop as shown above.

How Variable Scope Works in Python

In Python, variable names are local to the function by default. Global variables in Python are accessible both inside and outside of functions. Variables inside of functions, are only accessible inside of those functions. Variables and parameters assigned in a function occupy the local scope. A scope is a container of sorts for variables. When variables are assigned outside of functions, they occupy the global scope. There is only one global scope in a program, and it is created upon program initialization. A local scope comes into play any time a function is called. Consider these points about variables in Python:

  • Code in the global scope cannot use any variables in a local scope.
  • Code in a local scope can access variables in the global scope.
  • A nested function’s code can access the local scope of the outer function.
  • You can use the same name for different variables if they are in different scopes.

We can see the code snippet just above throws a NameError since you can not access a function defined variable in the global scope. If we need to get access to that variable, we can do so simply by declaring that variable as global. This is how we can do that.

Closure in Python

As we have learned in JavaScript, when a nested function reaches outside of it’s own local scope to access a non global variable that is part of an outer function, then we have closure. The outer function however, does not have access to the inner functions variables. Python makes use of this construct, and we can see an example of this in action right here.

How Do Functions Work in Python Summary

Functions allow for the programmer to create short, focused snippets of code that can be re used throughout an entire program. In functions, variables exist in a local scope. Therefore, code in the local scope of one function can’t access variables in the local scope of another function. One exception to this is when a function is nested inside another function. In this case, the inner function does have access to the outer function’s local scope. Functions help organize code into more manageable sub groups of software. They operate in a black box type of manner by accepting particular inputs as parameters, and outputs or returns values after computation.