21. Functions

You have called functions since Chapter 7 — print, input, int, random.randint, math.sqrt. Now you write your own: a function names a chunk of work you can reuse.

Defining and calling

The simplest definition:

def greet():
    print("Hello!")

greet()   # prints Hello!
greet()   # prints Hello! again

Read it as: define a function greet that takes no arguments and runs the body when called. The colon opens the body; indentation closes it. Call it by writing its name with ().

Python has no local keyword. Functions defined at the top of a file are available throughout that file. Keep them there unless you have a reason to nest them.

Parameters

A function takes inputs as parameters in parentheses:

def greet(name):
    print(f"Hello, {name}!")

greet("Keiko")    # Hello, Keiko!
greet("Python")   # Hello, Python!

name lives for one call; the caller supplies its value (the argument) by position. With more than one:

def add(a, b):
    print(f"{a} + {b} = {a + b}")

add(3, 4)   # 3 + 4 = 7

Python does not silently accept extra arguments — calling add(1, 2, 3) raises a TypeError. Missing arguments also raise a TypeError unless the parameter has a default value (see below).

Default parameters

A parameter can have a default value. If the caller skips it, the default is used:

def greet(name="World"):
    print(f"Hello, {name}!")

greet("Keiko")   # Hello, Keiko!
greet()          # Hello, World!

Parameters with defaults must come after parameters without defaults.

return — handing a value back

To produce a value instead of printing, use return:

def square(n):
    return n * n

result = square(5)
print(result)              # 25
print(square(7))           # 49
print(square(3) + 1)       # 10

return ends the function at once and hands the value back. A function with no return returns None.

Open exercises/21/01-square.py. Add a function cube(n) that returns n ** 3, then call cube(3).

Multiple return values

A Python function can return several values at once as a tuple:

def divmod_custom(a, b):
    return a // b, a % b

q, r = divmod_custom(17, 5)
print(q, r)   # 3 2

Python packs the two values into a tuple (3, 2) and the multi-assignment on the left unpacks them into q and r. You saw the same idea in Chapter 11 with the swap trick a, b = b, a — that works for the same reason.

You can also capture the tuple as a single variable and unpack later:

result = divmod_custom(17, 5)
print(result)      # (3, 2)
print(result[0])   # 3

Early return for guard checks

Since return ends the function at once, it is handy for the easy cases first:

def absolute(n):
    if n >= 0:
        return n
    return -n

print(absolute(5))    # 5
print(absolute(-7))   # 7

No else is needed: if the first branch matches, the function exits there and the line after the if never runs. This is a guard, or early return.

Scope: where variables live

A variable created inside a function lives only for that call. Once the function returns, those variables are gone:

def counter_step():
    count = 0
    count = count + 1
    return count

print(counter_step())   # 1
print(counter_step())   # 1   (not 2)
print(counter_step())   # 1

Every call gets a fresh count. To keep a value across calls, declare it outside the function:

count = 0

def step():
    global count
    count = count + 1
    return count

print(step())   # 1
print(step())   # 2
print(step())   # 3

The global count line tells Python that count inside step refers to the one at module level, not a new local. You will use this pattern occasionally — but a cleaner approach for shared state is covered in the classes chapter later.

Homework

Problem 1 — Greet

Open exercises/21/homework/01-greet.py. Write a function greet(name) that prints Hello, <name>!. Call it with three different names.

Problem 2 — is_even

Open exercises/21/homework/02-is-even.py. Write is_even(n) that returns (not prints) True or False for whether n is even. Call it on a few values inside print so the booleans show.

Problem 3 — Clamp

Open exercises/21/homework/03-clamp.py. Write clamp(x, lo, hi) that returns lo if x is below lo, hi if above hi, and x otherwise. Test it with three calls covering each case.

Challenge — Swap

Open exercises/21/homework/04-swap.py. Write swap(a, b) that returns the two values with positions exchanged. Then declare two variables, call swap on them, capture the results back into the same names, and print before and after — using both multi-return and multi-assignment from Chapter 11.

Stuck or finished? Open the homework solutions page.