Skip to content

Programming & Web Development · Guide

How to write a function in Python

def, a name, brackets, a colon, an indented body. Then the parts that matter: parameters, return values, defaults, and the mutable default trap that catches everyone.

The Nextversity teamProgramming & Web Development schoolUpdated August 10, 20266 min read

On this page
  1. The short answer
  2. return versus print
  3. Parameters and arguments
  4. The mutable default trap
  5. Write a docstring
  6. What makes a good function
  7. Scope, briefly
  8. Where to go next

The short answer

def greet(name):
    return f"Hi {name}, welcome aboard."

message = greet("Sam")
print(message)

Five pieces: def, a name, brackets holding parameters, a colon, and an indented body. Call it by writing its name with brackets and any arguments.

That is the syntax. The rest of this is the judgment: what goes in a function, what comes back out, and the two mistakes that catch nearly everyone.

return versus print

The single most common beginner confusion.

print displays something to the person running the program. The value is gone afterwards.

return hands a value back to the code that called the function, so it can be stored, tested or passed on.

def add_bad(a, b):
    print(a + b)          # shows it, gives nothing back

def add_good(a, b):
    return a + b          # hands the number back

total = add_good(2, 3)    # total is 5
doubled = add_good(2, 3) * 2

A function that prints instead of returning is a dead end. It cannot be tested, reused or combined. Return the value and let the caller decide whether to print it.

A function with no return gives back None, which is perfectly fine for functions that exist to do something rather than compute something.

Parameters and arguments

Parameters are the names in the definition. Arguments are the values you pass in when calling.

def make_label(product, price, currency="USD"):
    return f"{product}: {price} {currency}"

make_label("Notebook", 12)                    # positional
make_label("Notebook", 12, "EUR")             # positional
make_label(price=12, product="Notebook")      # keyword, any order

Keyword arguments are worth using whenever a call would otherwise be a row of unexplained values. send(True, False, True) tells a reader nothing. send(retry=True, silent=False, log=True) tells them everything.

The mutable default trap

This one catches everybody once, so learn it before it catches you:

def add_item(item, basket=[]):     # broken
    basket.append(item)
    return basket

The default list is created once, when the function is defined, not each time it is called. So the second call gets the first call's list, still holding its item.

The fix:

def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    return basket

Use None as the default for anything mutable: lists, dictionaries, sets.

Every Python developer has debugged this once, usually for twenty minutes, usually while insisting the computer is wrong.

Write a docstring

A triple-quoted string on the first line of the body:

def convert(amount, rate):
    """Convert an amount using a rate, rounded to two decimal places."""
    return round(amount * rate, 2)

Editors show it when you hover the function, help(convert) prints it, and future you reads it. One sentence is enough. PEP 257 covers the conventions if you want them.

What makes a good function

  • One job. If the name needs the word "and", it is probably two functions.
  • A name that says what it returns. calculate_total beats do_stuff, and is_valid reads well in an if.
  • Few parameters. More than four is a sign that a dictionary or a small class would be tidier.
  • No surprises. A function called get_user should not delete anything.
  • Short. If it does not fit on a screen, it is doing too much.

These are not style points. They are what makes code you can still read in six months, which is the only measure that matters in the long run.

Scope, briefly

Variables created inside a function exist only inside it. That is a feature: it means a function cannot accidentally break the rest of your program.

A function can read variables from outside, but assigning to one creates a new local variable instead of changing the outer one. If you find yourself reaching for global, there is nearly always a better design, usually passing the value in and returning the result.

Where to go next

Functions are the point where programs stop being scripts and start being structured. After them come modules (functions grouped in files), then classes when data and behavior belong together. The official tutorial section on functions covers the syntax formally.

The Python certificate walks through functions with practice, and the advanced certificate covers structure, modules and larger projects. If you are earlier than this, the beginner roadmap sets out the order.

One subscription opens the whole Programming & Web Development school.

Write small functions that return things. That habit alone will make your code better than most beginner code.

Questions people ask

How do you define a function in Python?

Use def, the function name, brackets holding any parameters, and a colon. The body is indented underneath. Call it later by writing its name followed by brackets.

What is the difference between return and print?

print shows text to the person running the program. return hands a value back to the code that called the function, so it can be stored or used. A function that prints instead of returning is hard to reuse.

What happens if a function has no return?

It returns None. That is fine for functions that exist to do something rather than calculate something, such as writing a file.

What are default arguments in Python?

Values used when the caller does not supply one, written as def greet(name, greeting="Hi"). Never use a mutable default like an empty list, because it is created once and shared between calls.

What are args and kwargs?

They let a function accept any number of positional or keyword arguments. Useful for wrappers and flexible interfaces, and not something a beginner needs on day one.

Keep reading