Foundations — ` - args` and ` - kwargs` — flexible argument passing
Before you can understand that sentence, you must own every word and symbol in it. This page builds them one at a time, from absolute zero. Nothing below assumes you already know the previous topic — we earn each piece.
The atoms, in build order
1. A value and a variable
The picture: imagine a labelled box on a shelf. The box holds the value; the label is the variable name. Figure s01 shows the name tag x pointing at the value 5 inside the box — trace the pink arrow from the tag to the box.

Figure s01 — a variable is a name tag pointing at a value stored in a box.
Why the topic needs it: *args and **kwargs are themselves just variable names that end up pointing at a bucket of values. If "name points at value" isn't solid, nothing else lands.
2. A function — a machine with input slots
Read def add(a, b): as: "Define a machine named add that has two input slots, a and b." The word return means "hand this value back to whoever called me."
Figure s02 draws this literally: the values 2 and 3 (pink arrows) enter the two slots a and b, the machine runs return a + b, and the result 5 leaves on the yellow arrow.

Figure s02 — inputs flow into named slots, the machine computes, an output flows out.
- The slots
aandbinside the parentheses are called parameters (the names on the machine). - When you actually run it,
add(2, 3), the2and3are arguments (the values you feed in).
Why the topic needs it: *args/**kwargs are a special kind of parameter. You can't understand a flexible slot until you understand a fixed slot. See Functions and Parameters.
3. Positional vs keyword arguments
This distinction is the hinge the whole topic turns on.
Figure s03 contrasts the two. In the top row (positional) the values slot in by their order; in the bottom row (keyword) the arrows cross because b=3 is written first yet still lands in slot b.

Figure s03 — positional filling relies on order; keyword filling relies on names (arrows can cross).
Why the topic needs it: *args catches the positional leftovers; **kwargs catches the keyword leftovers. They are two buckets precisely because there are two ways to pass a value. Miss this split and the whole topic looks arbitrary.
4. A tuple — an ordered, locked-shut list
The picture: a row of numbered pigeonholes, sealed with tape. You can read pigeonhole 0, 1, 2… but you cannot re-stuff them.
Why the topic needs it: the parent note states "*args is a tuple." That sentence is empty unless you know what a tuple is and why it was chosen.
5. A dictionary — a set of name → value pairs
The picture: a real dictionary book — you don't ask "the 4th word," you ask "the word apple" and get its meaning. Figure s04 shows each key box (name, age) mapping by an arrow to its value box — no position numbers anywhere, only names.

Figure s04 — a dict looks things up by name: each key maps to its value.
Why the topic needs it: keyword arguments already come as name → value pairs (age=20). The perfect container for name→value pairs is a dict — so **kwargs collects them into a dict. See Dictionaries.
6. The star * and double-star ** symbols
Now the two symbols the topic is named after. They have one meaning stated two ways: "unbundle / rebundle a group."
Why the topic needs it: literally the two characters the chapter is about. The single most common confusion (per the parent's mistakes) is forgetting that direction flips between def and call.
7. Iteration — walking through a group one item at a time
The picture: a hand sliding along the row of pigeonholes, pausing at each one.
Why the topic needs it: once *args has bundled the values into a tuple, you almost always loop over them (e.g. to add them up). For dicts you loop over .items(), which hands you each (key, value) pair.
8. A default value — a slot with a fallback
Why the topic needs it: defaults and catch-alls are cousins — both make a function's signature flexible. They also share the parameter-ordering rules the topic cares about. Details in Default Arguments.
9. Keyword-only parameters — slots you must name
The moment you put *args in a signature, a brand-new kind of slot appears after it.
Why the topic needs it: keyword-only parameters are not a separate lesson — they fall out automatically from placing *args in a signature. You cannot correctly order a signature without knowing this slot exists.
10. The parameter-ordering rule — the one legal sequence
You now have every kind of slot. They can only appear in one order, and Python enforces it.
Why the topic needs it: this is the rule the parent note leans on. Every valid def f(a, b, *args, **kwargs) and every rejected permutation is explained by the single sequence above.
11. Forwarding — one function calling another with the same inputs
The picture: a mail sorter who receives a sealed parcel and, without opening it, drops it into the next mailbox unchanged.
Why the topic needs it: this is the payoff. A wrapper that catches with *args, **kwargs and re-calls func(*args, **kwargs) can wrap any function — which is exactly the mechanism behind Decorators.
How the foundations feed the topic
Read it top-down: values live in variables, variables fill function slots, slots split into positional vs keyword, each kind gets a matched container via the star operators, *args births keyword-only slots, the ordering rule locks the whole signature down, and forwarding ties it all into the real-world payoff.
Equipment checklist
Test yourself — say the answer out loud before revealing.
What is the difference between a parameter and an argument?
def; argument = the actual value passed at the call.What matches a positional argument to its slot?
What matches a keyword argument to its slot?
age=20, so order stops mattering.What kind of container is a tuple, and can you change it?
Why is a tuple (not a list) the right home for *args?
What is a dict and how do you look things up in it?
Why does **kwargs produce a dict?
In a definition, what does * do?
In a call, what does *mylist do?
Does * at a call site work on any iterable?
What is the difference in direction of * between def and call?
What is a keyword-only parameter and when does it appear?
*args (or a bare *); it can only be passed by name.What is the one legal parameter order in a def?
*args → keyword-only → **kwargs.Why is def f(**kwargs, *args) a SyntaxError?
**kwargs absorbs all remaining keywords, so nothing may follow it; it must be last.What does for key, value in d.items(): give you each pass?
(key, value) pair from the dict.What does forwarding with func(*args, **kwargs) let a wrapper do?
Connections
- Yeh note Hinglish mein →
- Functions and Parameters — the machine-with-slots these foundations extend.
- Default Arguments — the other flexibility tool for function signatures.
- Tuples — the container
*argsproduces. - Dictionaries — the container
**kwargsproduces. - Unpacking Assignment — the same star idea used in
a, *rest = [1, 2, 3]. - Decorators — where forwarding pays off.