Arguments
Python gives you a lot of flexibility in how arguments are passed to functions. Understanding the options makes library documentation much easier to read.
Positional arguments
Matched to parameters by position.
def describe(name, age):
print(f"{name} is {age}")
describe("Ravi", 30)The number of arguments must match, or Python raises TypeError.
Keyword arguments
Matched by name, so order does not matter and the call documents itself.
def describe(name, age):
print(f"{name} is {age}")
describe(age=30, name="Ravi")Positional arguments must come before keyword arguments in a call.
Default values
A parameter with a default is optional.
def power(base, exponent=2):
return base ** exponent
print(power(5))
print(power(5, 3))
print(power(exponent=4, base=2))Parameters with defaults must come after those without.
def add(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add(1))
print(add(2))*args: any number of positional arguments
The extra arguments arrive as a tuple.
def total(*numbers):
print(numbers)
return sum(numbers)
print(total(1, 2, 3))
print(total())**kwargs: any number of keyword arguments
They arrive as a dictionary.
def show(**details):
for key, value in details.items():
print(f"{key} = {value}")
show(name="Ira", city="Goa", age=25)Combining them
The order in a definition is always: positional, *args, keyword only, **kwargs.
def report(title, *values, unit="", **meta):
print(title, values, unit, meta)
report("Temps", 31, 33, 29, unit="C", city="Jaipur")Unpacking arguments in a call
* spreads a list into positional arguments; ** spreads a dictionary into keyword arguments.
def area(w, h):
return w * h
size = [4, 5]
print(area(*size))
opts = {"w": 2, "h": 3}
print(area(**opts))Keyword only and positional only
A bare * in the definition forces everything after it to be passed by keyword. A / forces everything before it to be positional.
def connect(host, port, *, timeout=10):
print(host, port, timeout)
connect("db.local", 5432, timeout=5)
# connect("db.local", 5432, 5) would be an errorThis is why you see calls like sorted(items, key=..., reverse=True) and never sorted(items, f, True).
Practice
- Write
average(*nums)that returns the mean of any number of values and returns 0 for no values. - Write
make_tag(name, **attrs)that returns an HTML tag string, somake_tag("a", href="/x", id="l")gives<a href="/x" id="l">. - Rewrite
powerso that the exponent must be given by keyword.
