Parameters and arguments
Functions become really useful when you can give them information to work with. The names in the definition are parameters; the values you pass when calling are arguments.
def greet(name): # name is a parameter
print(f"Hello, {name}!")
greet("Asha") # "Asha" is an argument
greet("Leo")Several parameters
def describe_pet(animal, name):
print(f"I have a {animal} called {name}.")
describe_pet("dog", "Rex")
describe_pet("cat", "Mittens")Arguments are matched to parameters by position: the first argument goes to the first parameter, and so on. Swap them and you get nonsense:
def describe_pet(animal, name):
print(f"I have a {animal} called {name}.")
describe_pet("Rex", "dog")The right number of arguments
Every parameter needs an argument (unless it has a default, coming up soon):
def add(a, b):
print(a + b)
add(2)Arguments can be any expression
def show_total(price, quantity):
print(f"Total: {price * quantity:.2f}")
base = 40
show_total(base * 1.18, 3)
show_total(round(19.999, 2), len(["a", "b"]))Passing a list
When you pass a list, the function receives the same list, not a copy. If the function changes it, the caller sees the change:
def add_task(tasks, task):
tasks.append(task)
my_tasks = ["email"]
add_task(my_tasks, "call Mei")
print(my_tasks)This is sometimes exactly what you want. When it isn't, pass a copy (add_task(my_tasks.copy(), ...)) or have the function build and return a new list.
Numbers and strings behave differently because they are immutable: a function cannot change the caller's number, it can only make a new one.
def double(n):
n = n * 2 # makes a new number; the caller's variable is untouched
print("inside:", n)
x = 5
double(x)
print("outside:", x)