Defaults, keyword arguments, *args and **kwargs: how the values in a call find their way into the function.
The names in the def line: empty slots waiting for values.
The values in a call. Positional ones fill slots left to right; name=value goes to the slot with that name.
Unfilled slots take their default. Extra values go to *args or **kwargs, if the function has them.
On the next slides, press → to watch each call's arguments fly into place, and use the Try buttons for other calls.
# parameter with default value
def greet(name="Guest"):
print(f"Hello, {name}!")
greet()
# ans: Hello, Guest!
greet("Alice")
# ans: Hello, Alice!
# multiple default parameters
def create_user(name, age=0, city="Unknown"):
return f"{name}, {age}, {city}"
result = create_user("Alice")
# ans: "Alice, 0, Unknown"
# call with keyword arguments
def describe(animal, name):
print(f"{animal} named {name}")
describe(name="Rex", animal="dog")
# ans: dog named Rex
Keywords are matched by name, so their order in the call doesn't matter.
*args
# accept any number of arguments
def sum_all(*numbers):
return sum(numbers)
result = sum_all(1, 2, 3, 4)
# ans: 10
The star packs every positional argument into one tuple.
**kwargs
# accept any keyword arguments
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25)
# ans: name: Alice
# ans: age: 25
Two stars pack every keyword argument into one dict.
Predict the answer, then press → to see the arguments bind.
# what is printed?
def func(x=5):
print(x)
func()
# ans: 5
func(10)
# ans: 10
# default parameter order?
def func(a, b=10):
return a + b
func(5)
# ans: 15
# can you do this?
def func(a=5, b):
return a + b
# ans: SyntaxError (non-default after default)
A call like func(1) couldn't tell whether 1 is for a or b, so Python forbids it: parameters with defaults come last.
# keyword arguments?
def func(a, b):
return a - b
func(b=10, a=5)
# ans: -5 (5 - 10)
# mixing positional and keyword?
def func(a, b, c):
return a + b + c
func(1, c=3, b=2)
# ans: 6
# *args type?
def func(*args):
return type(args)
func(1, 2, 3)
# ans: <class 'tuple'>
# **kwargs type?
def func(**kwargs):
return type(kwargs)
func(a=1, b=2)
# ans: <class 'dict'>
# combining parameters?
def func(a, b=5, *args):
return a + b + sum(args)
func(1, 2, 3, 4)
# ans: 10 (1+2+3+4)
2 fills b, so its default is never used.
# empty *args?
def func(*args):
return len(args)
func()
# ans: 0
# mutable default parameter?
def func(x=[]):
x.append(1)
return x
func()
func()
# ans: [1, 1] (same list object!)
Fix: use x=None and create the list inside, with if x is None: x = [].
Positional left to right, then keywords by name, then defaults for any gaps.
def f(a=5, b) is a SyntaxError.
*args is a tupleExtra positional values, possibly empty.
**kwargs is a dictExtra keyword values, by name.
A mutable default like [] is shared by every call.