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()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 itsdefis aNameError. - Don't forget the
(). Plaingreetjust 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")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")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")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))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))print vs return
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)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))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]))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)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))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))
Start with def rectangle_area(width, height): and indent the body underneath.
The body needs only one line: return width * height.
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))
A comparison already gives back True or False, so you can return it directly.
Return the result of n % 2 == 0.
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([]))
if not numbers: is true when the list is empty. Return 0 in that case.
Otherwise return sum(numbers) / len(numbers).
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]
Use if / elif with a return in each branch, checking the highest grade first.
After the function, loop with for score in scores: and print(score, get_grade(score)).
Summary
def name(parameters):defines a function, andname(arguments)calls it.- Parameters are the names in the definition. Arguments are the values you pass in.
returnsends a value back and ends the function. Without it, a function returnsNone.printshows a value, whilereturngives 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.
Know something worth teaching? Write your own tutorial with runnable examples and share it.