Skip to content

Python3 Functions

A function is an organized, reusable block of code used to implement a single, or related, functionality.

Functions improve application modularity and code reuse. You already know that Python provides many built-in functions, such as print(). But you can also create your own functions, which are called user-defined functions.


You can define a function with the functionality you want. Here are the simple rules:

  • The function code block begins with the def keyword, followed by the function identifier name and parentheses ().
  • Any incoming parameters and arguments must be placed inside the parentheses, which can be used to define parameters.
  • The first line of the function can optionally use a docstring — used to store the function description.
  • The function content starts with a colon : and is indented.
  • return [expression] ends the function, optionally returning a value to the caller. A return without an expression is equivalent to returning None.


Python uses the def keyword to define a function. The general format is as follows:

def function_name(parameter_list):
    function_body

By default, parameter values and parameter names are matched in the order declared in the function definition.

Let’s use a function to output “Hello World!”:

#!/usr/bin/python3

def hello() :
    print("Hello World!")

hello()

A more complex application, with parameter variables in the function:

Compare two numbers and return the larger one:

#!/usr/bin/python3
 
def max(a, b):
    if a > b:
        return a
    else:
        return b
 
a = 4
b = 5
print(max(a, b))

Output of the above example:

5

Compute area function:

#!/usr/bin/python3
 
# Compute area function
def area(width, height):
    return width * height
 
def print_welcome(name):
    print("Welcome", name)
 
print_welcome("Runoob")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))

Output of the above example:

Welcome Runoob
width = 4  height = 5  area = 20

Defining a function: gives the function a name, specifies the parameters contained in the function, and the code block structure.

After the basic structure of the function is completed, you can call it from another function, or directly from the Python command prompt.

The following example calls the printme() function:

#!/usr/bin/python3
 
# Define a function
def printme( str ):
   # Print any incoming string
   print (str)
   return
 
# Call the function
printme("I want to call a user-defined function!")
printme("Call the same function again")

Output of the above example:

I want to call a user-defined function!
Call the same function again

In Python, types belong to objects, and objects have different types. Variables have no type:

a=[1,2,3]

a="Runoob"

In the above code, [1,2,3] is of type List, “Runoob” is of type String, and the variable a has no type — it is merely a reference (a pointer) to an object, which can point to a List type object or a String type object.

In Python, strings, tuples, and numbers are immutable objects, while lists, dicts, and others are mutable objects.

  • Immutable types: Variable assignment a=5 followed by a=10 — this actually creates a new int value object 10, and then makes a point to it, while 5 is discarded. The value of a is not changed; rather, a is newly generated.

  • Mutable types: Variable assignment la=[1,2,3,4] followed by la[2]=5 — this changes the value of the third element of list la. la itself does not change; only a part of its internal value is modified.

Parameter passing in Python functions:

  • Immutable types: Similar to pass-by-value in C++, such as integers, strings, tuples. For example, fun(a) passes only the value of a, without affecting the a object itself. If you modify the value of a inside fun(a), a new object for a is generated.

  • Mutable types: Similar to pass-by-reference in C++, such as lists, dictionaries. For example, fun(la) actually passes la itself, so modifications inside fun will affect la outside.

In Python, everything is an object. Strictly speaking, we cannot say pass-by-value or pass-by-reference; we should say passing immutable objects and passing mutable objects.

Use the id() function to see memory address changes:

def change(a):
    print(id(a))   # Points to the same object
    a=10
    print(id(a))   # A new object
 
a=1
print(id(a))
change(a)

Output of the above example:

4379369136
4379369136
4379369424

You can see that before and after calling the function, the formal parameter and the actual parameter point to the same object (same object id). After modifying the formal parameter inside the function, the formal parameter points to a different id.

If a mutable object’s parameter is modified inside a function, the original parameter in the calling function is also changed. For example:

#!/usr/bin/python3
 
# Writable function description
def changeme( mylist ):
   "Modify the incoming list"
   mylist.append([1,2,3,4])
   print ("Value inside function: ", mylist)
   return
 
# Call the changeme function
mylist = [10,20,30]
changeme( mylist )
print ("Value outside function: ", mylist)

The object passed into the function and the one with new content appended at the end use the same reference. Thus the output is:

Value inside function:  [10, 20, 30, [1, 2, 3, 4]]
Value outside function:  [10, 20, 30, [1, 2, 3, 4]]

The following are the formal parameter types that can be used when calling a function:

  • Required parameters
  • Keyword parameters
  • Default parameters
  • Variable-length parameters

Required parameters must be passed into the function in the correct order. The number of calls must be the same as in the declaration.

To call the printme() function, you must pass in one parameter; otherwise, a syntax error occurs:

#!/usr/bin/python3
 
# Writable function description
def printme( str ):
   "Print any incoming string"
   print (str)
   return
 
# Calling printme without a parameter will cause an error
printme()

Output of the above example:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    printme()
TypeError: printme() missing 1 required positional argument: 'str'

Keyword parameters are closely related to function calls. Function calls use keyword parameters to determine the parameter values passed in.

Using keyword parameters allows the order of parameters in a function call to differ from the declaration, because the Python interpreter can match parameter values using parameter names.

The following example uses parameter names when calling the printme() function:

#!/usr/bin/python3
 
# Writable function description
def printme( str ):
   "Print any incoming string"
   print (str)
   return
 
# Call the printme function
printme( str = "Runoob Tutorial")

Output of the above example:

Runoob Tutorial

The following example demonstrates that function parameters do not need to be used in the specified order:

#!/usr/bin/python3
 
# Writable function description
def printinfo( name, age ):
   "Print any incoming string"
   print ("Name: ", name)
   print ("Age: ", age)
   return
 
# Call the printinfo function
printinfo( age=50, name="runoob" )

Output of the above example:

Name:  runoob
Age:  50

When calling a function, if no parameter is passed, the default parameter is used. In the following example, if the age parameter is not passed in, the default value is used:

#!/usr/bin/python3
 
# Writable function description
def printinfo( name, age = 35 ):
   "Print any incoming string"
   print ("Name: ", name)
   print ("Age: ", age)
   return
 
# Call the printinfo function
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )

Output of the above example:

Name:  runoob
Age:  50
------------------------
Name:  runoob
Age:  35

You may need a function that can handle more parameters than those declared initially. These parameters are called variable-length parameters. Unlike the two types above, they are not named when declared. The basic syntax is as follows:

def functionname([formal_args,] *var_args_tuple ):
   "function_docstring"
   function_suite
   return [expression]

Parameters with an asterisk * will be imported as a tuple, storing all unnamed variable parameters.

#!/usr/bin/python3
  
# Writable function description
def printinfo( arg1, *vartuple ):
   "Print any incoming parameters"
   print ("Output: ")
   print (arg1)
   print (vartuple)
 
# Call the printinfo function
printinfo( 70, 60, 50 )

Output of the above example:

Output: 
70
(60, 50)

If no parameters are specified when calling the function, it becomes an empty tuple. We can also avoid passing unnamed variables to the function. As shown below:

#!/usr/bin/python3
 
# Writable function description
def printinfo( arg1, *vartuple ):
   "Print any incoming parameters"
   print ("Output: ")
   print (arg1)
   for var in vartuple:
      print (var)
   return
 
# Call the printinfo function
printinfo( 10 )
printinfo( 70, 60, 50 )

Output of the above example:

Output:
10
Output:
70
60
50

There is also a parameter with two asterisks **. The basic syntax is as follows:

def functionname([formal_args,] **var_args_dict ):
   "function_docstring"
   function_suite
   return [expression]

Parameters with two asterisks ** will be imported as a dictionary.

#!/usr/bin/python3
  
# Writable function description
def printinfo( arg1, **vardict ):
   "Print any incoming parameters"
   print ("Output: ")
   print (arg1)
   print (vardict)
 
# Call the printinfo function
printinfo(1, a=2,b=3)

Output of the above example:

Output: 
1
{'a': 2, 'b': 3}

When declaring a function, the asterisk * can appear alone in the parameter list, for example:

def f(a,b,*,c):
    return a+b+c

If the asterisk * appears alone, parameters after the asterisk * must be passed using keywords:

>>> def f(a,b,*,c):
...     return a+b+c
... 
>>> f(1,2,3)   # Error
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # OK
6
>>>

Python uses lambda to create anonymous functions.

“Anonymous” means no longer using the standard def statement to define a function.

  • lambda is just an expression; the function body is much simpler than def.
  • The body of a lambda is an expression, not a code block. Only limited logic can be encapsulated in a lambda expression.
  • lambda functions have their own namespace and cannot access parameters outside their own parameter list or in the global namespace.
  • Although lambda functions appear to be single-line, they are not equivalent to inline functions in C or C++. The purpose of inline functions is to avoid occupying stack memory when calling small functions, thereby reducing function call overhead and improving code execution speed.

The syntax of a lambda function contains only one statement, as follows:

lambda [arg1 [,arg2,.....argn]]:expression

Set parameter a to add 10:

x = lambda a : a + 10
print(x(5))

Output of the above example:

15

The following example sets two parameters for an anonymous function:

#!/usr/bin/python3
 
# Writable function description
sum = lambda arg1, arg2: arg1 + arg2
 
# Call the sum function
print ("Value after addition: ", sum( 10, 20 ))
print ("Value after addition: ", sum( 20, 20 ))

Output of the above example:

Value after addition:  30
Value after addition:  40

We can encapsulate anonymous functions within a function, allowing us to use the same code to create multiple anonymous functions.

The following example encapsulates an anonymous function within the myfunc function, creating different anonymous functions by passing different parameters:

def myfunc(n):
  return lambda a : a * n
 
mydoubler = myfunc(2)
mytripler = myfunc(3)
 
print(mydoubler(11))
print(mytripler(11))

Output of the above example:

22
33

For more on anonymous functions, see: Python lambda (Anonymous Functions)


The return [expression] statement is used to exit a function, optionally returning an expression to the caller. A return statement without a parameter value returns None. The previous examples did not demonstrate how to return a value. The following example demonstrates the usage of the return statement:

#!/usr/bin/python3
 
# Writable function description
def sum( arg1, arg2 ):
   # Return the sum of two parameters.
   total = arg1 + arg2
   print ("Inside function: ", total)
   return total
 
# Call the sum function
total = sum( 10, 20 )
print ("Outside function: ", total)

Output of the above example:

Inside function:  30
Outside function:  30

Python 3.8 introduced a new function parameter syntax / to indicate that certain function parameters must use positional arguments and cannot use keyword arguments.

In the following example, parameters a and b must use positional arguments, c or d can be positional or keyword arguments, and e and f must be keyword arguments:

def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)

The following usage is correct:

f(10, 20, 30, d=40, e=50, f=60)

The following usage will cause errors:

f(10, b=20, c=30, d=40, e=50, f=60)   # b cannot use keyword argument form
f(10, 20, 30, 40, 50, f=60)           # e must use keyword argument form

Practice Exercises