Menu Close


Python: functions

Python is mostly structured, but it has functional, declarative and object oriented capabilities. In Python you can define named blocks of code that can be executed on demand. These can be called functions, procedures, methods or subroutines. We chose to call them functions in Python.

Python Function

In Python we use keyword “def” to define a light-weight object that can act like a function or like a method. This block can be called by name to calculate one or more values called results. A function that do not have results is called in other languages subroutine, procedure or void function.  In Python there is no distinction between a normal function and a subroutine with no result.


In this example we define a function that have a side-effect but does not return a result:

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Test this example live: Fibonacci


The description of a function can be created using triple quotes and string as the first statement after the function declaration. This can be used to find information about function using: help(<function_name>)


Functions can return a result that can be captured into a variable using assign operator “=”. It can also be used into an expression. In the example below we calculate a mathematical function: “f(n) = !n” (factorial) using a recursive function call. That is a function that call itself with different parameters until a condition becomes True:


Function parameters, sometimes called “formal parameters” are in fact local variables that can receive values from a function call. Parameters can be mandatory or optional. Mandatory parameters are usually declared first. Optional parameters, have a “default value” specified in parameter declaration using notation “param = value” or “param:type = value.


To execute a function we use function name follow by a list of arguments enclosed in round brackets and separated by comma: function_name(arg, arg, …). The parenthesis are mandatory after the function name even if there are no mandatory formal parameters defined.

Arguments are paired-up by position or by name using equal sign. Mandatory and optional arguments can coexist in a call. For mandatory parameters we can assign arguments by position while optional parameters can receive arguments by name. We can also use names for all arguments, but this is unusual practice.


Next example is using what you have learned so far to create a median function. This function is good only for 2 up to 5 numbers. It also has a logical defect to establish the divisor in case of zero value arguments.

Homework: Copy the example from here: optional and then make a better version using variable argument “varargs”, that you will learn later in this article. Post your snippet on Discord or make a Gist on GitHub and brag about it on the forum. I will give you kudos and reputation points.

Variable arguments

A procedure can receive a list of arguments into one special parameter. This feature is sometimes called: “varargs” or “rest”. For declaring this parameter we use prefix “*”. This parameter becomes a collection of values visible in local scope. 


Homework: Test this snippet on-line: Varargs

Note: In the example above I have used a new syntax available since Python 3.6, that enables you to specify parameters types, variable types and function result type. This may surprise you since you know, Python is a dynamic language. It is a good practice to use this style of programming.

Type hinting may improve program readability but does not affect performance. It was introduced to improve programming experience for developers. Python can use type hinting to avoid logical mistakes for large projects. 


A namespace is a composite word from “name” and “space”. It represents a block of code that hold several identifiers. A namespace is defined by a “scope”. This is a region of a program used to define: variables, constants and functions. 


Test this example live: Namespaces

Output of the program:

Name Space Details

The namespaces are nested. The outermost scope is called “global” scope and it create a “global” namespace. Functions can be nested. Inside every function there is a local namespace.


Using “=” will create a new variable in the local scope. If a variable exists already defined in the global scope or in the parent scope it is shadowed. We create a new variable in the local scope that hide the outer scope variable.

To avoid shadowing we have to declare variables using “global” or “nonlocal” keywords. This is necessary for every single nested function that uses other variables than the local variables.

Function attributes

In Python a function is an object. Any object can have attributes that can be created using a dot operator. Function attributes are attached to the function as static variables. This is another alternative to global variables and it can be used to create encapsulated functions that behave like objects.


In the next example the function test_attr() is creating an attribute called counter the first time is called. Then the attribute is used to memorize the current counter value. Next time is able to return the value and increment it for next call.

Test this example live: Attributes

Test output:

Read next: Classes