Click to share! ⬇️

Python Function Tutorial

Functions are named blocks of code designed to do one specific job. Functions allow you to write code once that can then be run whenever you need to accomplish the same task. Functions can take in the information they need, and return the information they generate. Using functions effectively makes your programs easier to write, read, test, and fix. In this tutorial, we will learn how to define a function, how to pass arguments, define parameters, set default values, and more.


How To Define A Function In Python

To define a function in Python, you can use the def keyword. Immediately following the def keyword is the name of the function, and after that is a set of parentheses() and a colon:. The body of a function is indented one level. According to PEP 8, the Style Guide for Python Code, an indentation level should be 4 spaces. To call a function, simly write the name of the function followed by parentheses().

Define a Python Function

def hello_world():
    print('Hello World!')


hello_world()
Hello World!

Python Function Arguments And Parameters

When you call a function, you may pass information into it. This is what is known as an argument. Arguments are included in parentheses after the function’s name when calling the function. When you define a function that expects to receive a piece of information, it is referred to as a parameter. Parameters are listed in parentheses in the function’s definition.

Passing a single argument

def hello_friend(friend):
    print(f'Hello, {friend}!')


hello_friend('Mosely')
hello_friend('Winnie')
Hello, Mosely!
Hello, Winnie!

Pass a List As An Argument

If you need to pass several values to a function at once, you may do this using a list. The function is able to work with the values in the list. The original list is modified if the function makes any changes to the list. If you need to keep the original list intact, you can pass a copy of the list as an argument.

Passing a list as an argument

def hello_friends(names):
    for name in names:
        message = f'Hello, {name}!'
        print(message)


hello_friends(['Winnie', 'Mosely', 'Bella', 'Mugsy'])
Hello, Winnie!
Hello, Mosely!
Hello, Bella!
Hello, Mugsy!

Allowing a function to modify a list

The following shows how the original list is being modified during the execution of the function. The list starts with 4 names, but has 0 names after the function runs.

def hello_friends(names):
    while names:
        name = names.pop()
        message = f'Hello, {name}!'
        print(message)


original = ['Winnie', 'Mosely', 'Bella', 'Mugsy']
print(original)
hello_friends(original)
print(original)
['Winnie', 'Mosely', 'Bella', 'Mugsy']
Hello, Mugsy!
Hello, Bella!
Hello, Mosely!
Hello, Winnie!
[]

Preventing a function from modifying a list

In this example we ensure the original list stays intact by passing a copy of the original list to the function.

def hello_friends(names):
    while names:
        name = names.pop()
        message = f'Hello, {name}!'
        print(message)


original = ['Winnie', 'Mosely', 'Bella', 'Mugsy']
copy = original[:]
print(original)
hello_friends(copy)
print(original)
['Winnie', 'Mosely', 'Bella', 'Mugsy']
Hello, Mugsy!
Hello, Bella!
Hello, Mosely!
Hello, Winnie!
['Winnie', 'Mosely', 'Bella', 'Mugsy']

Positional and keyword arguments

Arguments can be positional or keyword-based. Positional arguments simply line up the first argument in the function call with the first parameter in the function definition, and so on. Keyword arguments rely on the programmer to specify which parameter each argument should be assigned to in the function call. The order does not matter with keyword arguments.

Using positional arguments

def describe_car(make, model):
    print(f'The {make} {model} is a neat vehicle')


describe_car('Subaru', 'WRX')
describe_car('Tesla', 'Model 3')
describe_car('Tesla', 'Cybertruck')
The Subaru WRX is a neat vehicle
The Tesla Model 3 is a neat vehicle
The Tesla Cybertruck is a neat vehicle

Using keyword arguments

def describe_car(make, model):
    print(f'The {make} {model} is a neat vehicle')


describe_car('Subaru', 'WRX')
describe_car(make='Tesla', model='Model 3')
describe_car(model='Corvette', make='Chevy')
The Subaru WRX is a neat vehicle
The Tesla Model 3 is a neat vehicle
The Chevy Corvette is a neat vehicle

Default values

You can specify a parameter by default if you like. That way, when the function is called, if an argument is not provided, the default value will be used. Parameters with default values must be listed after parameters without default values in the function’s definition to ensure positional arguments will still work.

Using a default value

def describe_car(make, model='WRX'):
    print(f'The {make} {model} is a neat vehicle')


describe_car('Subaru')
The Subaru WRX is a neat vehicle

Using None to make an argument optional

def describe_car(make, model=None):
    if model:
        print(f'The {make} {model} is a neat vehicle')
    else:
        print(f'The {make} is a neat vehicle')


describe_car('Subaru')
describe_car(model='Corvette', make='Chevy')
The Subaru is a neat vehicle
The Chevy Corvette is a neat vehicle

Passing an arbitrary number of arguments

If you don’t know how many arguments a function will need when it is called, then you can use the asterisk * operator to collect an arbitrary number of arguments. A parameter that accepts a variable number of arguments must come last in the function definition. If you would like to do this with keyword arguments, then use the double-asterisk ** operator. These arguments are stored as a dictionary with the parameter names as keys, and the arguments as values.

Function with an arbitrary number of arguments

def make_a_sandwich(type, *veggies):
    print(f'nMaking a {type} Sandwich.')
    print('It has these veggies:')
    for veggie in veggies:
        print(f'- {veggie}')


make_a_sandwich('Ham', 'Onions')
make_a_sandwich('Roast Beef', 'Lettuce', 'Tomato')
make_a_sandwich('Turkey', 'Lettuce', 'Tomato', 'Peppers')
Making a Ham Sandwich.
It has these veggies:
- Onions

Making a Roast Beef Sandwich.
It has these veggies:
- Lettuce
- Tomato

Making a Turkey Sandwich.
It has these veggies:
- Lettuce
- Tomato
- Peppers

Collecting an arbitrary number of keyword arguments

def make_a_sandwich(type, **veggies):
    print(f'nMaking a {type} Sandwich.')
    print('It has these veggies:')
    for veggie in veggies:
        print(f'- {veggies[veggie]}')


make_a_sandwich('Ham', one='Onions')
make_a_sandwich('Roast Beef', one='Onions', two='Peppers')
make_a_sandwich('Turkey', one='Olives', two='Spinach', three='Cucumbers')
Making a Ham Sandwich.
It has these veggies:
- Onions

Making a Roast Beef Sandwich.
It has these veggies:
- Onions
- Peppers

Making a Turkey Sandwich.
It has these veggies:
- Olives
- Spinach
- Cucumbers

How to structure a function

We’ve seen a few ways to write and call functions so far. If you’re wondering what is the best way to structure the code, just try to get something that works. That is the main goal! With more experience, you’ll develop a sense of what makes different structures such as positional and keyword arguments more advantageous. As long as your functions are doing the work you want them to, then that is great.


Return values

A common piece of work functions do, is to return a value. In other words, you want to be able to give a function some data and have it give some other data or value back to you. To capture the returned value from a function, the calling line should provide a variable which the return value can be assigned to. Once the function reaches a return statement, it stops running.

Returning a single value

def get_full_name(first, last):
    full_name = f'{first} {last}'
    return full_name.title()


comedian = get_full_name('ricky', 'gervais')
print(comedian)
Ricky Gervais

Returning a dictionary

def build_house(type, bedrooms):
    house = {'type': type, 'bedrooms': bedrooms}
    return house


house = build_house('Colonial', 3)
print(house)
{'type': 'Colonial', 'bedrooms': 3}

Returning a dictionary with optional values

def build_house(type, bedrooms, pool=None):
    house = {'type': type, 'bedrooms': bedrooms}
    if pool:
        house['pool'] = pool
    return house


house = build_house('Colonial', 3)
print(house)

house = build_house('Colonial', 2, 'No')
print(house)
{'type': 'Colonial', 'bedrooms': 3}
{'type': 'Colonial', 'bedrooms': 2, 'pool': 'No'}

Modules

In Python, functions can be stored in a separate file, then imported when needed. This is what is known as a Module. Modules facilitate cleaner program files. When using a module, you’ll want to store the module file in the same directory as the main program.

Storing a function in a module

sandwichmaker.py

def make_a_sandwich(type, *veggies):
    print(f'nMaking a {type} Sandwich.')
    print('It has these veggies:')
    for veggie in veggies:
        print(f'- {veggie}')

Importing an entire module

functions.py
Every function in the module is available in the program file.

import sandwichmaker

sandwichmaker.make_a_sandwich('Pastrami', 'Lettuce', 'Tomato')
sandwichmaker.make_a_sandwich('Corned Beef', 'Pickles', 'Jalapenos')
Making a Pastrami Sandwich.
It has these veggies:
- Lettuce
- Tomato

Making a Corned Beef Sandwich.
It has these veggies:
- Pickles
- Jalapenos

Importing a specific function

Only the imported functions are available in the program file.

from sandwichmaker import make_a_sandwich

make_a_sandwich('Egg', 'Lettuce', 'Tomato')
make_a_sandwich('Steak', 'Pickles', 'Relish')
Making a Egg Sandwich.
It has these veggies:
- Lettuce
- Tomato

Making a Steak Sandwich.
It has these veggies:
- Pickles
- Relish

Giving a module an alias

import sandwichmaker as s

s.make_a_sandwich('Honey Ham', 'Spinach', 'Tomato')
s.make_a_sandwich('Angus Roast Beef', 'Avacado', 'Sun Dried Tomato')
Making a Honey Ham Sandwich.
It has these veggies:
- Spinach
- Tomato

Making a Angus Roast Beef Sandwich.
It has these veggies:
- Avacado
- Sun Dried Tomato

Giving a function an alias

from sandwichmaker import make_a_sandwich as mas

mas('Honey Ham', 'Spinach', 'Tomato')
mas('Angus Roast Beef', 'Avacado', 'Sun Dried Tomato')

Importing all functions from a module

It is possible to import all functions using the wildcard, but it can result in naming conflicts, which can cause errors. It is best to avoid this practice

from sandwichmaker import *

make_a_sandwich('Honey Ham', 'Spinach', 'Tomato')
make_a_sandwich('Angus Roast Beef', 'Avacado', 'Sun Dried Tomato')

Learn More About Python Functions


Python Function Tutorial Summary

All programming languages allow you to bundle up a sequence of instructions that you want to re-use as you see fit. Python is no different, and also provides the ability to simplify programs by making use of these reusable pieces of functionality. A function is just a piece of code that is used to complete a specific task. Functions can make use of data passed into them and may return various types of data, though they are not required to.

Click to share! ⬇️