Functions
Learn how to write reusable blocks of code called functions to organize your programs and avoid repeating yourself.
Write once, use many times
A function is a named block of code that does a specific job. You write it once, then you can use it, which is called calling it, as many times as you want anywhere in your program. Functions help you avoid repeating the same code, make programs easier to read, and let you break big problems into small manageable pieces.
You have already used built-in functions like print(), len(), input() and int(). Now you will learn to create your own.
Use the def keyword, then the function name, then parentheses, then a colon. The code inside must be indented:
def greet():
print("Hello, World!")
print("Welcome to Python.")
greet() # call the function
greet() # call it again
Hello, World!
Welcome to Python.
Hello, World!
Welcome to Python.
There are two steps, and they are different. Defining (def) only teaches Python the recipe. Nothing runs yet. Calling (greet()) is what actually runs the recipe. If you define a function but never call it, nothing happens. Also, a function must be defined before the line that calls it.
Parameters
Parameters are inputs you give to a function so it can do different things with different data. They are the names inside the brackets of the def line:
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # Hello, Alice!
greet("Bob") # Hello, Bob!
greet("Charlie") # Hello, Charlie!
You can have multiple parameters, separated by commas:
def add(a, b):
print(a + b)
add(3, 5) # 8
add(10, 20) # 30
A small piece of vocabulary: the names in the def line (a, b) are parameters. The real values you pass when calling (3, 5) are arguments. Arguments are matched to parameters by position, so the first argument goes into the first parameter.
You can also pass arguments by name, which makes calls easier to read and lets you change the order:
def describe(animal, sound):
print(f"A {animal} says {sound}.")
describe(sound="moo", animal="cow") # A cow says moo.
If you give the wrong number of arguments, Python raises a TypeError.
Return values
A function can calculate something and send the result back. Use the return keyword:
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
print(add(10, 20) + 5) # 35
When a function hits return, it stops immediately and sends the value back. Any code after the return in that function does not run.
def check(n):
return "big"
print("This never runs")
What is the difference between printing and returning? print only shows something on the screen. return hands the value back to the code that called the function, so you can store it or use it in more math. Most of the time you want return.
def double(n):
return n * 2
x = double(4) + double(3) # 8 + 6
print(x) # 14
A function with no return gives back None, which means "nothing". You can also return several values at once, separated by commas, and unpack them: low, high = get_range().
Default parameter values
You can give parameters default values. If the caller does not provide that argument, the default is used:
def greet(name, message="Hello"):
print(f"{message}, {name}!")
greet("Alice") # Hello, Alice!
greet("Bob", "Good morning") # Good morning, Bob!
Parameters with defaults must come after the ones without. This makes functions flexible. The common case stays short, and anyone who needs something different can override it.
def power(base, exponent=2):
return base ** exponent
print(power(3)) # 9, uses the default exponent 2
print(power(3, 3)) # 27
Many built-in functions work this way. For example, print() ends with a new line by default, and round(x) rounds to a whole number unless you give a second argument.
Variable scope
Variables created inside a function only exist inside that function. They cannot be accessed from outside. This is called local scope:
def my_function():
x = 10 # x only exists inside this function
print(x)
my_function() # 10
print(x) # Error! x does not exist outside the function
Why is that a good thing? Every function gets its own private workspace. Two functions can both use a variable called total without ever interfering. A variable made outside every function is global, and functions can read it:
tax_rate = 0.2 # global
def add_tax(price):
return price + price * tax_rate
print(add_tax(100)) # 120.0
A function can read a global variable, but assigning to that name inside the function creates a new local variable instead of changing the global one. Rather than reaching outside, pass values in as parameters and send results out with return. That keeps functions simple and easy to test.
Putting functions to work
def calculate_total(price, quantity, tax_rate=0.1):
subtotal = price * quantity
tax = subtotal * tax_rate
total = subtotal + tax
return total
def print_receipt(item, price, quantity):
total = calculate_total(price, quantity)
print(f"Item: {item}")
print(f"Price: ${price:.2f}")
print(f"Quantity: {quantity}")
print(f"Total: ${total:.2f}")
print("---")
print_receipt("Apple", 0.50, 6)
print_receipt("Bread", 2.99, 2)
print_receipt("Milk", 1.25, 3)
Notice how print_receipt calls calculate_total. Functions can use other functions, so you build big things from small reliable pieces. Each function does one job. This idea of breaking a big problem into smaller problems is called decomposition, and it is a core skill of every good programmer.
Writing good functions
- Pick a verb for the name.
calculate_total,get_nameandis_eventell you what happens. - Keep it small. If you cannot describe the job in one sentence, split it.
- Add a docstring. A short note under the
defline explains what it does. - Return a value instead of printing, unless showing something is the job.
- Avoid secrets. A function should depend only on its parameters, not on hidden variables.
def is_even(number):
"""Return True if number is even, otherwise False."""
return number % 2 == 0
print(is_even(4)) # True
print(is_even(7)) # False
Functions that return True or False are very handy inside an if: if is_even(n): reads almost like English. Test your functions with a few different inputs, including odd ones like 0 and negative numbers.
Functions that take any number of values
Sometimes you do not know how many arguments will come. A parameter that starts with a star collects all extra arguments into a tuple:
def total(*numbers):
result = 0
for n in numbers:
result += n
return result
print(total(1, 2)) # 3
print(total(5, 10, 15, 20)) # 50
This is how print() can accept any number of items. You do not need this every day, but it is good to recognize it when you see *args in other code.
Functions are also values. You can store one in a variable or put it in a dictionary, which is the trick used in the calculator project later:
def square(n):
return n * n
operation = square
print(operation(5)) # 25
Key takeaways
def name(parameters):defines a function, andname(arguments)calls it- Parameters are the inputs. Arguments are the actual values you pass
returnsends a value back and ends the function. NoreturnmeansNone- Default values like
exponent=2make arguments optional - Variables made inside a function are local and disappear after it ends
- Small, well named functions that do one job are the heart of clean code