Flexible Python Function Signatures: Mastering *args and **kwargs

Python functions can be declared to accept an open-ended number of positional or named inputs. Two special syntax forms—*args and **kwargs—make this posisble without hard-coding every parameter in advance.

Collecting Extra Positional Values with *args

Prefixing a parameter with a single asterisk instructs the enterpreter to bundle any surplus positional arguments into a tuple. Inside the body, you can iterate or index this tuple like any other sequence.

def total(*numbers):
    acc = 0
    for n in numbers:
        acc += n
    return acc

print(total(5, 7, 9))        # 21
print(total(1, 2, 3, 4, 5))  # 15

Gathering Arbitrary Keyword Arguments with **kwargs

Two asterisks in front of a parameter name collect any extra keyword arguments into a dictionary whose keys are the argument names and whose values are the supplied data.

def build_profile(**fields):
    for k, v in fields.items():
        print(f"{k}: {v}")

build_profile(name="Alice", age=28, city="Berlin")
# name: Alice
# age: 28
# city: Berlin

Mixing Fixed, Positional-Variable, and Keyword-Variable Parameters

All three kinds of parameters can coexist in one signature, provided they appear in the order: positional, *args, then **kwargs.

def log_event(level, message, *extras, **meta):
    print(f"[{level}] {message}")
    if extras:
        print("Extra data:", extras)
    for key, val in meta.items():
        print(f"  {key} -> {val}")

log_event("WARN", "Disk space low", "/var", "/tmp",
          source="monitoring", timestamp="2024-06-12T09:41:00Z")
# [WARN] Disk space low
# Extra data: ('/var', '/tmp')
#   source -> monitoring
#   timestamp -> 2024-06-12T09:41:00Z

Tags: python args-kwargs function-signatures variadic-functions

Posted on Fri, 14 Aug 2026 16:22:18 +0000 by nitharsanke