You’ve seen def a hundred times. You know how to write a function, call it, and return a value. But do you know what really happens when Python executes a function definition? Do you know why args and kwargs exist, or how a function can remember the environment where it was created? In Python, functions are more than just reusable blocks of code — they’re objects with attributes, they can be nested, passed as arguments, and wrapped by decorators. In this article, we’ll move from the basics of def and return to the powerful patterns that make Python feel like Python. Whether you’re a beginner or brushing up, there’s something here for you.
A function is a block of organised,reusable code that is used to perform an action.
There are two basic types of functions we can work with: built-in functions and user-defined functions.
We can break down the creation of a function into five components.
Function definition
In Python, we use the keyword "def" to define a function, followed by round brackets and a colon. The colon is used to indicate the start of a new block of code.
Function name
We need to give our function a name which we will use to call it later.
There are some guidelines on how to name a function, such as the name must begin with a letter or an underscore, it must be in lowercase, it can have numbers and be any length (it's best to keep it short), it cannot be the same as any Python keyword, and must describe the function's purpose.
Function inputs
Inputs, also known as parameters, define the variables required for the function to perform its tasks. It's worth noting that we don't have to submit an input every time. If the function tasks do not require any inputs, we can leave this field empty.
It is essential to differentiate between function parameters and arguments.
Parameters are variables listed in the function declaration, serving as placeholders for the values that the function will receive during its execution. They act as local variables within the function, defining its input structure. On the other hand, arguments are the actual values passed to a function when it is called. These values are assigned to the corresponding parameters defined in the function, allowing for dynamic and flexible behaviour.
Function instructions/tasks
This is the block of code within the function that serves as the set of instructions that the function must follow. To indicate that the code that follows belongs to the function, we type it one tab away from the declaration line.
Return statement
The return statement defines what the result of the function or the output should be.
Note: A return statement is not required for the function to be created successfully. However, because every function in Python must return something, functions that do not have a return statement return None by default.
Create the function
We start by typing def to define the function, followed by the function name, which we called calc_forest_area.
Our function has two arguments, the forest length and width.
We add these arguments in the brackets and end the declaration with a colon after the brackets.
Pressing enter in most coding environments will take us to the next line at the correct level of indentation. However, if it doesn't, we hit the tab button, which is equivalent to four or eight whitespaces, depending on the Python editor.
Inside the function, we define a new variable called area and set it equal to our input length multiplied by our input width. This is the instruction that will calculate our area.
Next, we define what we want our function to return using the return statement. In our case, we want our function to return the area of the forest calculated by the function.
Therefore, we add “return” and the area variable.
Call the function
Assume we wanted to use our newly created function to determine the area of the Zambesi forest which has a length of 300 kilometres and a width of 5000 kilometres.

We could also store our output in a variable in order to use it later.

Remember when we made use of built-in functions and could read the documentation using the help() function? We can employ documentation strings to perform something similar for user-defined functions.
Documentation strings, abbreviated docstrings, are used to describe the functionality of a function, including the arguments and expected return, if they exist. Docstrings can also be used in other code constructs, such as classes and methods, to provide additional information to the user.
The purpose of any docstring is to explain the function's purpose and functionality so that anyone new viewing or using it understands what the function does.
Doc Strings
A docstring is most commonly defined under the function definition with triple double quotation marks and is divided into three distinct sections:
- Functionality of the function.
- Breakdown of the input(s), if applicable.
- Breakdown of the output, if applicable.
Let's add some docstrings to our calc_forest_area function.

Docstrings are not required for our functions to execute successfully, however, there are some advantages to using them.
Docstrings improve code readability by allowing anyone viewing it to grasp its intent without having to decipher it, making collaboration easier. In our code base, we tend to construct several functions that perform a variety of tasks. Having documentation that explains what the function does and how to use it makes it easier to keep track of all our functions. We are also able to access the documentation for all our functions using the doc attribute, as well as the built-in help() function.
Scope
Now that we understand how to create a function, we need to understand scope, which refers to the parts of our code where an object or variable is available for use.
We can distinguish between a local variable and a global variable.
Local variable
When we created our function, within it we created a variable called area.
This variable is known as a local variable.
A local variable is defined in or by a function and is only available for use inside that function.
For instance, if we attempted to access our area variable from outside the function, we would receive an error stating that the variable name has not been defined.
Global variable
In contrast, a global variable is one that is defined outside of any function's construct and can be accessed anywhere in our code.
The zambesi_forest variable we created earlier, for example, is a global variable that can be used globally in our code, even inside a function.
Function inputs
Functions in Python are like tools that perform specific tasks. To make these tools versatile, we need a way to provide them with information. Inputs in functions serve this purpose, allowing us to customise the function's behaviour based on different situations.
Types of inputs
No input
Sometimes, a function doesn't require any input to perform its task. For example, suppose we wanted to write a function that would print a general deforestation message throughout our program at various phases.

This function does not require any input from the user in order to produce the desired outcome.
Default inputs
Default inputs provide a way to set default values for named arguments in a function. If a value is not provided when calling the function, the default value is used.
Suppose we wanted to give the user the option of entering their own personalised message if they so desired. In this case, we could use default arguments.

A user who does not need a personalised message could use the function without providing a value for the message argument.

Alternatively, a user that needs a unique message can use the message parameter to specify it.

In the above examples, the message parameter has a default value, making it optional when calling the function.
Variable inputs
Sometimes, we might want a function to accept an arbitrary number of arguments without specifying their names.
Python provides us with two variadic inputs – *args and **kwargs.
For us to understand *args and **kwargs, it's important for us to understand the difference between keyword arguments and non-keyword arguments.
Keyword arguments
Keyword arguments are used when we call a function and explicitly assign an argument to a parameter. The sequence in which we pass the arguments does not matter when using keyword arguments, because we explicitly assign the parameters to the variable.
In the function call above, we used keyword parameters to call the create_deforestation_message function. We entered the message and then the location to explicitly assign each argument to its parameter, regardless of order.
Positional arguments/Non-keyword arguments
When we call a function in Python and supply arguments based on the position of the parameters, the arguments are referred to as positional arguments. Positional arguments are thus matched with parameters based on their position. Positional arguments are often known as "non-keyword arguments".

We utilised positional parameters in the function call above to call the create_deforestation_message function. The arguments were entered in the correct sequence depending on their placement in the function parameters.
Unlike keyword arguments, if we changed the order of these parameters, the function wouldn't perform as expected.
*args: Variable non-keyword arguments
*args enable a function to accept any number of positional arguments, that is, non-keyword arguments in a variable-length argument list.
An *args parameter is created in the same way as any other parameter, with the exception that an asterisk is added before the parameter name.
Suppose we also wanted to create a function that allows the user to track the impact of deforestation on their forest. We could write a function that takes each consequence as an argument, but users may want to list a varying number of consequences or arguments. This would be possible with *args.
**kwargs: Keyword arguments
**kwargs indicate that our function can accept any number of keyword arguments by placing ** before the parameter name. The arguments will be wrapped in a dictionary with the key being the parameter name and the value being the parameter value.
Suppose we want to create a function that collects detailed and varying characteristics of a forest. The user must be able to decide what information they would like to share using this function.
We can create a function named list_forest_details that accepts any number of keyword arguments and uses a combination of the parameter name and value to output labelled information about the forest.
In this function, **details allows the function to accept any number of keyword arguments. It iterates through the dictionary and prints each key-value pair.
Note: If our function were to make use of both *args and **kwargs, it is important to remember that we always place *args before **kwargs in the argument list.
Multiple return values
Python functions are very versatile and can be configured to meet the needs of the user. We just proved this through our exploration of the number of ways users can enter inputs into our functions. This remains true for function return values.
Python functions can return function results in several ways. We can return a string, a number, a dictionary, a tuple, or even a table as a value.
Python can also return multiple values.
In some cases, a function needs to provide more than one piece of information back to the user. This can be accomplished by separating the values with a comma. The values returned can then be allocated to numerous variables. This can come in handy in a variety of scenarios.
Let's create a function that calculates the impact of deforestation caused by carbon emissions.
We want our function to compute the percentage of tree cover loss by subtracting the initial forest area from the remaining forest area.
We also want it to estimate the increase in CO2 emissions by multiplying the tree cover percentage, the remaining forest area, and the carbon emission factor.
The function returns a tuple containing the percentage of tree cover loss, the remaining forest area, and the estimated increase in CO2 emissions. To use these values, we unpack the tuple into separate variables (loss_percentage, remaining_area, and co2_increase) when calling the function.
We can then use or view each variable separately.

By exploring the above concepts, we have gained practical insights into how to create versatile and useful functions in Python.








Top comments (0)