Skip to content
Laviyx Learn

Try

Python course menu

Python Function Parameters: Defaults, *args, **kwargs and Type Hints

Learn every kind of Python function parameter: required parameters, default values, the mutable default trap, *args for any number of values, **kwargs for named options, keyword-only parameters, and type hints.

Beginner7 min readUpdated
On this page

Parameters are the names listed in a function's definition. They decide what information a function needs and how callers can pass it. (The values passed in when calling are arguments, covered in the next lesson.)

Required parameters#

Python
def greet(name, greeting):
    print(f"{greeting}, {name}!")

greet("Asha", "Hello")
Output
Hello, Asha!

Every parameter without a default must receive a value:

Python
greet("Asha")
Output
TypeError: greet() missing 1 required positional argument: 'greeting'

Default values#

Give a parameter a default with =. Callers can then leave it out:

Python
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Asha")
greet("Ravi", "Welcome")
Output
Hello, Asha!
Welcome, Ravi!

Parameters with defaults must come after those without. Defaults make functions flexible: callers specify only what differs from the usual case.

Python
def make_order(item, qty=1, gift_wrap=False):
    wrap = " (gift wrapped)" if gift_wrap else ""
    return f"{qty} x {item}{wrap}"

print(make_order("Notebook"))
print(make_order("Pen", 10))
print(make_order("Book", gift_wrap=True))
Output
1 x Notebook
10 x Pen
1 x Book (gift wrapped)

The mutable default trap#

Default values are created once, when the function is defined, not each time it is called. With a list as a default, every call shares the same list:

Python
def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item("a"))
print(add_item("b"))
Output
['a']
['a', 'b']

The second call "remembered" the first. The fix is to use None and create the list inside:

Python
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item("a"))
print(add_item("b"))
Output
['a']
['b']

*args: any number of positional values#

A parameter starting with * collects all extra positional arguments into a tuple:

Python
def total(*numbers):
    print(numbers)
    return sum(numbers)

print(total(1, 2, 3))
print(total())
Output
(1, 2, 3)
6
()
0

print() itself works this way, which is why it accepts any number of values.

**kwargs: any number of named values#

A parameter starting with ** collects extra keyword arguments into a dictionary:

Python
def profile(name, **details):
    print(name, details)

profile("Asha", age=21, city="Pune")
Output
Asha {'age': 21, 'city': 'Pune'}

The names args and kwargs are only conventions; the * and ** do the work.

Keyword-only parameters#

Parameters after a bare * must be passed by name. That makes calls self-explanatory and prevents mix-ups:

Python
def describe(name, *, city):
    return f"{name} from {city}"

print(describe("Asha", city="Pune"))
print(describe("Asha", "Pune"))
Output
Asha from Pune
TypeError: describe() takes 1 positional argument but 2 were given

The full order#

When combining them, parameters must appear in this order:

Python
def f(required, optional="x", *args, keyword_only, **kwargs):
    ...

Type hints#

You can annotate parameters and the return value with types. Python does not enforce them at runtime, but editors and tools like mypy use them to catch mistakes:

Python
def area(width: float, height: float = 1.0) -> float:
    return width * height

print(area(3, 4.5), area(2))
Output
13.5 2.0

Common mistakes#

Practice#

Practice exercise

Write price_with_tax(price, rate=0.18, round_to=2) that returns the price including tax, rounded to round_to decimal places. Call it three ways: only a price; a price and a 5% rate; and a price of 99.99 rounded to 0 decimal places using a keyword argument.

Show hint

round(price * (1 + rate), round_to).

Show solution
Python
def price_with_tax(price, rate=0.18, round_to=2):
    return round(price * (1 + rate), round_to)

print(price_with_tax(100))
print(price_with_tax(100, 0.05))
print(price_with_tax(99.99, round_to=0))
Output
118.0
105.0
118.0

The keyword round_to=0 lets you skip rate and keep its default.

Key takeaway#

Finished this lesson?