Python Functions

Another crucial concept in programming languages is the function.

A function is a named section of a program that performs a specific task and, optionally, returns a value

You can define functions yourself, but Python also has built-in functions. Let's start with the most well known built-in function, called print:

>>> print('Hello, readers!')
Hello, readers!
>>> print(15)

Print takes an argument and prints it to the screen.

As stated in our definition, functions can optionally return a value. However, print does not return anything. Because it prints something to the screen, it might look like it does, but it doesn't. We can check this, by assigning the result of a print statement to a variable:

>>> result = print("Hello")
>>> print(result)

None is a special type of value in Python, basically meaning 'nothing.'

Another built-in function, that does return a value, is len. It returns the length of whatever you feed it:

>>> mylength = len('Hello')
>>> print(mylength)

Creating functions

Now that we know how to use a function, let's create one ourselves:

>>> def say_hi():
...     print('Hi!')
>>> say_hi()

It's just a few lines, but a lot is going on. Let's dissect this:

  • First of all, we see the word def, which is the Python keyword used to define a function.
  • Next comes our function name, say_hi.
  • Then we encounter two parentheses, (), which indicate that this function does not accept any arguments (unlike print and len).
  • We end the line with a colon (:)
  • And finally, we bump into a feature that sets Python apart from many other programming languages: indentation.


Python uses indentation to distinguish blocks of code that belong together. Consecutive lines with equal indentation are part of the same block of code.

To tell Python that the following lines are the body of our function, we need to indent them. You indent lines with the TAB-key on your keyboard. In Python, it's good style to use four spaces for indentation. The entire Python community does so. The Python interactive shell (REPL) and all decent editors will automatically indent with four spaces if you hit the TAB-key.

Back to our function: it has only one line of code in its body, the print command. After it, we hit enter one extra time to let the Python REPL know that this is the end of the function. Finally, we can call our function with say_hi().

Parameters and Arguments

We can make this more interesting by allowing an argument to be passed to our function:

>>> def say_hi(name):
...     print('Hi', name)
>>> say_hi('Erik')
Hi Erik

Our function now accepts a value, which we assign to the variable name. We call such variables the parameter, while the actual value we provide ('Erik') is called the argument.

Parameters and arguments
A function can have parameters. The values we pass it through these parameters are called arguments.

As you can see, print accepts multiple arguments, separated by a comma. This allows us to print both 'hi' and the provided name. For our convenience, print automatically puts a space between the two strings.

Variable scope

The variable name only exists inside our function. We say that the scope of the variable name is the function say_hi, meaning it doesn't exist outside of this function.

The visibility of a variable is called scope. The scope defines which parts of your program can see and use a variable.

If we define a variable at the so-called top-level of a program, it is visible in all places.

Let's demonstrate this:

>>> def say_hi():
...    print("Hi", name)
...    answer = "Hi"
>>> name = 'Erik'
>>> say_hi()
Hi Erik
>>> print(answer)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'answer' is not defined

say_hi was able to use the variable name, as expected, because it's a top-level variable that is visible everywhere. However, answer, defined inside say_hi, is not known outside of the function and causes a NameError.

Multiple arguments

Let's make this even wilder and define a function with multiple arguments:

>>> def welcome(name, location):
...     print("Hi", name, "welcome to", location)
>>> welcome('erik', 'this tutorial')
Hi erik welcome to this tutorial

It's not that hard, you just add more arguments to the function definition, separated by commas.

Default Values and Named Parameters

A compelling Python feature is the ability to provide default values for the parameters:

>>> def welcome(name='learner', location='this tutorial'):
...     print("Hi", name, "welcome to", location)
>>> welcome()
Hi learner welcome to this tutorial
>>> welcome(name='John')
Hi John welcome to this tutorial
>>> welcome(location='this epic tutorial')
Hi learner welcome to this epic tutorial
>>> welcome(name='John', location='this epic tutorial')
Hi John welcome to this epic tutorial

Because our parameters have a default value, you don't have to fill them in. If you don't, the default is used. If you do, you override the default with your own value.

Calling functions while explicitly naming the parameters, is different from what we did up until now. These parameters are called named parameters because we specify both the name and the value. Thanks to these named parameters the order in which we supply them doesn't matter. If you think about it, it's the natural and only way to make default values useful.

If you don't want to use named parameters, you can. When you rely on position instead of names, you're providing what we call positional parameters. The position matters, as can be seen below:

>>> def welcome(name='learner', location='this tutorial'):
...     print("Hi", name, "welcome to", location)
>>> welcome('Erik', 'your home')
Hi Erik welcome to your home

If you liked this page, please share it with a fellow learner: