Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk3 min

How to Use *args and **kwargs in Python Functions

A practical guide to Python’s *args and **kwargs: how collection differs from call-site unpacking, how keyword-only parameters work, and how to forward arguments without common binding errors.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In a Python function definition, *args collects extra positional arguments into a tuple, while **kwargs collects extra keyword arguments into a dictionary. In a function call, the same markers do the reverse: *iterable unpacks values as positional arguments, and **mapping unpacks entries as keyword arguments. Knowing whether the markers collect or unpack depends on whether they appear in a definition or a call.

What *args and **kwargs collect

The names args and kwargs are conventions, not special Python identifiers. The asterisks determine the behavior. This function shows both kinds of collection:

def describe(first, *args, **kwargs):
    print("first:", first)
    print("extra positional:", args)
    print("extra keywords:", kwargs)

describe("hello", 1, 2, color="blue")

first receives "hello". The extra positional values, 1 and 2, are collected in args, a tuple: (1, 2). The extra keyword argument is collected in kwargs, a dictionary: {"color": "blue"}. Keywords that match explicitly declared parameters bind to those parameters instead of being collected.

The Python 3.14.8 Tutorial describes the positional behavior this way: “These arguments will be wrapped up in a tuple (see Tuples and Sequences).” Python Tutorial: Arbitrary Argument Lists

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Collection in a definition versus unpacking in a call

In a definition, the markers gather arguments supplied by the caller. At a call site, they unpack an iterable or mapping into arguments. These are related but distinct operations.

Syntax Where it appears What it does Result or input
def f(*args): Function definition Collects remaining positional arguments A tuple inside the function
def f(**kwargs): Function definition Collects remaining keyword arguments A dictionary inside the function
f(*items) Function call Unpacks an iterable into positional arguments Values supplied to the call
f(**options) Function call Unpacks a mapping into keyword arguments Named values supplied to the call

For example, these values can supply the two parameters of greet:

def greet(name, punctuation="!"):
    return f"Hello, {name}{punctuation}"

positional = ["Ada"]
options = {"punctuation": "."}
greet(*positional, **options)

The call is equivalent to greet("Ada", punctuation="."). The iterable supplies positional values; the mapping supplies keyword values. Keys unpacked with ** must be strings usable as keyword names, and the resulting call must not assign the same parameter twice.

How keyword-only parameters work

Any parameters declared after *args must be passed by keyword. This lets a function accept a variable number of positional values while keeping options clearly named:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
def log(message, *args, sep=" "):
    return message + sep + sep.join(map(str, args))

log("values:", 1, 2, sep=" | ")

Here, message binds first, 1 and 2 go into args, and sep is keyword-only. A bare * can create the same boundary without collecting extra positional arguments:

def connect(host, *, timeout):
    ...

connect("example.com", timeout=5)

Python also supports a slash (/) in a signature to mark preceding parameters as positional-only. The slash and the star are separate controls: / limits how earlier parameters may be supplied, while * marks where keyword-only parameters begin.

Forward arguments through a wrapper

A wrapper can accept arguments it does not interpret and forward them to another function:

def wrapper(x, *args, **kwargs):
    return target(x, *args, **kwargs)

The wrapper consumes x and passes it along with the remaining positional and keyword arguments. It can also inspect or change kwargs before forwarding, but the wrapper should make clear which options it handles and which it passes on. For a stable public interface, explicitly naming supported parameters is often easier to understand and validate than accepting every possible argument.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common binding errors and how to diagnose them

  • Giving a parameter two values: f(1, x=2) raises TypeError if the first positional argument already binds to x. Supply it once, either positionally or by keyword.
  • Using an unknown keyword: a call such as f(color="blue") fails if the function has no color parameter and no **kwargs collector.
  • Passing a keyword-only parameter positionally: if it follows *args or a bare *, use its name in the call.
  • Expecting a list or tuple at the call site: *args in a definition creates a tuple, while **kwargs creates a dictionary. The variables themselves are ordinary local names.
  • Confusing collection with unpacking: def f(*args) gathers values; f(*items) expands an iterable. Check whether the syntax is in a definition or a call.

Choose a signature that communicates the function’s interface

Use explicit parameters when the supported inputs are known and should be discoverable from the signature. Add *args when a function genuinely accepts an arbitrary number of positional values, and **kwargs when it needs to accept arbitrary named options or transparently forward them. Variadic arguments offer flexibility, but can make unsupported or misspelled options harder to catch at the function boundary.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
  2. Cupertino desk5 min
    Apple Unveils AirPods Max 2: The Upgrade That Should Have Happened Years AgoAirPods Max 2 adds H2-powered audio features and Apple claims up to 1.5× more effective ANC, but its design, Smart Case, and 20-hour battery rating are unchanged. Wired lossless audio…
  3. Cupertino desk4 min
    Apple’s OLED Touch MacBooks Are Coming—but the Dynamic Island Is the Real GambleApple has not announced an OLED touchscreen MacBook, but reports point to high-end models arriving in late 2026 or early 2027. The reported Mac Dynamic Island could be useful, but…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.