Python
Function Call
Programming
Asterisk
Double Asterisk

What do double star/asterisk and star/asterisk mean in a function call?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python function calls, * and ** are unpacking operators. * expands an iterable into positional arguments, while ** expands a mapping into keyword arguments. The same symbols also appear in function definitions, where they collect arguments instead of expanding them, so it helps to learn both directions together.

* in a Function Call

* takes a sequence such as a list or tuple and unpacks its elements into separate positional arguments.

python
1def add(a, b, c):
2    return a + b + c
3
4values = [1, 2, 3]
5print(add(*values))

Without *, the function would receive one list argument instead of three positional arguments.

You can also mix explicit positional arguments with unpacked values.

python
1def show(a, b, c, d):
2    print(a, b, c, d)
3
4rest = (3, 4)
5show(1, 2, *rest)

That call is equivalent to show(1, 2, 3, 4).

** in a Function Call

** takes a mapping, usually a dictionary, and unpacks its keys and values into keyword arguments.

python
1def connect(host, port, timeout=30):
2    print(host, port, timeout)
3
4config = {"host": "localhost", "port": 5432, "timeout": 10}
5connect(**config)

This works only if the dictionary keys match the parameter names. If the mapping has an unexpected key, Python raises TypeError.

*args and **kwargs in Definitions

In a function definition, the meaning flips:

  • '*args collects extra positional arguments into a tuple'
  • '**kwargs collects extra keyword arguments into a dictionary'
python
1def audit(event, *args, **kwargs):
2    print("event:", event)
3    print("args:", args)
4    print("kwargs:", kwargs)
5
6audit("login", 101, "ok", ip="10.0.0.5", region="us-east")

At the call site, * and ** expand values outward. In the function definition, they gather values inward.

Why This Is Useful for Wrappers

These forms appear constantly in decorators, wrappers, and helper functions that forward calls without knowing the target signature in advance.

python
1def logged_call(func, *args, **kwargs):
2    print(f"Calling {func.__name__}")
3    return func(*args, **kwargs)
4
5
6def multiply(a, b):
7    return a * b
8
9print(logged_call(multiply, 6, 7))

This works because the wrapper collects arbitrary inputs and then forwards them with unpacking.

Argument Order Still Matters

Even with unpacking, normal Python binding rules still apply. Positional arguments come before keyword arguments, and you cannot provide the same argument twice.

python
1def report(name, *values, precision=2, **meta):
2    rounded = [round(v, precision) for v in values]
3    return {"name": name, "values": rounded, "meta": meta}
4
5print(report("latency", 12.345, 11.999, precision=1, unit="ms"))

Here precision is keyword-only because it appears after *values in the definition.

Multiple Unpackings Can Be Combined

Python also allows more than one unpacking source in the same call, as long as the final argument binding is valid.

python
1def show(a, b, c, d, e):
2    print(a, b, c, d, e)
3
4left = [1, 2]
5right = (4, 5)
6show(*left, 3, *right)

This flexibility is useful when arguments come from several sources and you want to combine them cleanly at the call site.

Common Pitfalls

A common mistake is assuming * and ** always mean multiplication and exponentiation. In function calls and definitions, they often mean unpacking and collecting instead.

Another is passing a dictionary with keys that do not match the function's parameter names. ** does not rename keys.

Developers also mix up the call-site meaning and the definition-side meaning. In a call, * expands. In a definition, *args collects.

Summary

  • In a function call, * unpacks an iterable into positional arguments.
  • In a function call, ** unpacks a mapping into keyword arguments.
  • In a function definition, *args collects extra positional arguments.
  • In a function definition, **kwargs collects extra keyword arguments.
  • Unpacking is especially useful in wrappers, decorators, and dynamic API calls.

Course illustration
Course illustration

All Rights Reserved.