Know some Python? Write your own interactive tutorial, with runnable examples and exercises, and share it with a link. Write and share your own tutorial.

Start writing

Learn Python / Functions

Functions

You've been using functions since your first lesson: print(), len(), input(), round(). Now you'll write your own. A function is a named block of code that does one job. You define it once, then call it as many times as you like.

Defining and calling a function

Use def, a name, parentheses and a colon. The indented block below is the function's body:

def greet():
    print("Hello!")
    print("Welcome to Python.")

greet()
greet()
Output

Defining a function doesn't run it. The body only runs when you call the function by writing its name followed by (). Each call runs the whole body from the top, which is why Hello! and Welcome to Python. appear twice.

Two rules that catch beginners:

  • Define before you call. Python reads from top to bottom, so calling greet() on a line above its def is a NameError.
  • Don't forget the (). Plain greet just refers to the function without running it; print(greet) shows something like <function greet at 0x...>.

Function names follow the same rules as variable names. By convention they're snake_case and usually start with a verb: calculate_total, send_email, is_valid.

Parameters: giving a function input

Put parameters inside the parentheses. They act like variables that get their values when the function is called:

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

greet("Ada")
greet("Grace")
Output

The values you pass in, "Ada" and "Grace", are called arguments. On the first call, name is "Ada"; on the second, name is "Grace". The two words are easy to mix up:

Word Where it appears Example
parameter in the def line: the name the function uses name in def greet(name):
argument in the call: the actual value passed in "Ada" in greet("Ada")

A parameter only exists inside its function. Using name outside greet is a NameError (the Scope lesson explains why).

A function can take several parameters, separated by commas. Arguments are matched to parameters by position: the first argument goes to the first parameter, and so on:

def describe_pet(name, animal):
    print(f"{name} is a {animal}.")

describe_pet("Rex", "dog")
describe_pet("Tom", "cat")
Output

Swap the arguments, as in describe_pet("dog", "Rex"), and you get dog is a Rex.. Python doesn't know what the values mean; it just goes by order. (The next lesson shows how to pass arguments by name instead.)

Passing the wrong number of arguments raises a TypeError:

def describe_pet(name, animal):
    print(f"{name} is a {animal}.")

describe_pet("Rex")
Output

return: getting a result back

So far our functions only print. Most useful functions return a value instead, so the caller can store it, use it in a calculation or pass it on:

def square(n):
    return n * n

result = square(5)
print(result)
print(square(3) + square(4))
Output

return ends the function immediately and sends the value back to wherever the function was called. You can picture square(5) being replaced by its result: result = square(5) becomes result = 25, and square(3) + square(4) becomes 9 + 16.

Any lines after a return in the same block never run:

def square(n):
    return n * n
    print("This never runs")

print(square(4))
Output

This difference trips up many beginners. print shows something on the screen, while return hands a value back to your program:

def add_print(a, b):
    print(a + b)

def add_return(a, b):
    return a + b

# shows 5, but x gets nothing
x = add_print(2, 3)

# shows nothing, but y is 5
y = add_return(2, 3)

print("x is", x)
print("y is", y)
Output

A function without a return statement returns None, Python's "no value". That's why x is None: add_print showed 5 on the screen but handed nothing back. So add_print(2, 3) * 10 would be a TypeError, while add_return(2, 3) * 10 is 50.

print(value) return value
Shows something on screen yes no
Gives the value back to the caller no (gives None) yes
Ends the function no yes

As a rule, functions that calculate something should return it, and leave printing to the code that calls them.

Returning early

return can appear anywhere in the body, which makes it easy to handle special cases first:

def divide(a, b):
    if b == 0:
        return "Can't divide by zero"
    return a / b

print(divide(10, 2))
print(divide(5, 0))
Output

When b is 0, the first return ends the function, so the division on the last line is never attempted. A plain return with no value also works; it ends the function and gives back None.

Returning several values

Return several values separated by commas. Python packs them into a tuple, which you can unpack straight away:

def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([7, 2, 9, 4])
print(low, high)

# without unpacking, you get the tuple
print(min_max([7, 2, 9, 4]))
Output

It's still one return value, a tuple (2, 9), so the number of names you unpack into must match the number of values returned.

Docstrings

A docstring is a string on the first line of a function's body that explains what it does. It's written in triple quotes and indented like the rest of the body. Unlike a # comment, Python keeps it, so help() and code editors can show it:

def area_of_circle(radius):
    """Return the area of a circle with the given radius."""
    import math
    return math.pi * radius ** 2

print(round(area_of_circle(3), 2))
help(area_of_circle)
Output

Functions calling functions

Functions can call other functions. Small functions that each do one thing combine into bigger ones:

def celsius_to_fahrenheit(c):
    return c * 9 / 5 + 32

def describe_temperature(c):
    f = celsius_to_fahrenheit(c)
    if c >= 25:
        feel = "hot"
    elif c >= 15:
        feel = "mild"
    else:
        feel = "cold"
    return f"{c}°C ({f:.0f}°F) feels {feel}"

print(describe_temperature(30))
print(describe_temperature(8))
Output

Why use functions?

  • Reuse: write the logic once, call it everywhere.
  • Readability: calculate_tax(price) explains itself far better than the arithmetic inside it.
  • Easier fixes: if there's a bug, you fix it in one place.
  • Testing: a small function with clear input and output is easy to check.

Exercises

Exercise 1: Rectangle area

Write a function rectangle_area(width, height) that returns the area. The code below should then print 24 and 50.

# define rectangle_area here

print(rectangle_area(4, 6))
print(rectangle_area(10, 5))
Output

Exercise 2: Is it even?

Write a function is_even(n) that returns True if n is even and False otherwise.

# define is_even here

print(is_even(4))
print(is_even(7))
Output

Exercise 3: Average of a list

Write average(numbers) that returns the average of a list, or 0 if the list is empty.

# define average here

print(average([4, 8, 6]))
print(average([]))
Output

Exercise 4: Grade function

Turn the grading logic from the If / Elif / Else lesson into a function get_grade(score) that returns "A" for 90 and over, "B" for 80 and over, "C" for 70 and over, and "F" otherwise. Then use a loop to print each score followed by its grade, like 95 A.

# define get_grade here

scores = [95, 83, 71, 40]
Output

Summary

  • def name(parameters): defines a function, and name(arguments) calls it.
  • Parameters are the names in the definition. Arguments are the values you pass in.
  • return sends a value back and ends the function. Without it, a function returns None.
  • print shows a value, while return gives it back to your program.
  • Return several values with commas and unpack them: low, high = min_max(nums).
  • A docstring on the first line documents what the function does.

Share this tutorial

Know something worth teaching? Write your own tutorial with runnable examples and share it.