Function Arguments — Positional, Keyword, Default, Variable (Layered)

2140 words
11 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Function Arguments — Positional, Keyword, Default, and Variable Parameter Binding > [!SUMMARY] > **Sitting Scope:** 45–60 minutes. Complete mental model of argument binding, parameter order invariants, mutable default traps, exam pattern taxonomy, and interactive attempt-first drills.

Function Arguments — Positional, Keyword, Default, and Variable Parameter Binding

Summary
Sitting Scope: 45–60 minutes. Complete mental model of argument binding, parameter order invariants, mutable default traps, exam pattern taxonomy, and interactive attempt-first drills.

1. Orientation & Where It Sits

In procedural Python, defining a function creates a callable object in memory. However, the mechanism by which Python maps arguments passed at a call site to parameters declared in a function signature is governed by a strict, unambiguous binding grammar. Mastering this grammar is the line between guessing how code executes and knowing exactly what the interpreter does before it runs.
[Basic Functions & Return] (Week 7) ──┐
                                     ├──► [Function Arguments & Scope] (Week 8) ──► [Decorators & Functional Python] (Week 11)
[Lists, Tuples & Dicts]   (Weeks 5-6) ┘                                         └──► [OPPE Coding & Python Mocks] (Exam Desk)
  • Prerequisites:
  • Downstream Unlocks:
    • Recursion with Accumulators (798 - Recursion.md) — Passing default states across stack frames.
    • Higher-Order Functions & Decorators — Taking *args, **kwargs to wrap arbitrary callables.

2. Notation, Vocabulary & Etymology

TermSyntax / NotationSemantic MeaningMemory Hook
Parameterdef f(x, y):The named variables declared in a function definition header.The parking spot reserved in the function's blueprint.
Argumentf(10, 20)The actual concrete values or objects passed into the function at call time.The actual car parked in the spot.
Positional Argumentf(a, b)An argument bound to a parameter strictly by its sequential order (left-to-right).First-come, first-seated in a movie theatre row.
Keyword Argumentf(name="Ada")An argument bound explicitly to a parameter by name, regardless of position.A reserved seat with your name printed on the headrest.
Default Parameterdef f(mode="fast"):A fallback value assigned to a parameter if the caller provides no argument.A factory pre-set on a thermostat.
*args (Var-Positional)*argsSyntax packing zero or more positional arguments into a single tuple.An accordion: expands to absorb any number of loose items into a box.
**kwargs (Var-Keyword)**kwargsSyntax packing zero or more keyword arguments into a single dictionary.A labelled filing box: absorbs any name-value pairs into a map.
Unpacking Operatorf(*L) or f(**D)Expanding an iterable into positional args, or a dict into keyword args at call site.Emptying a backpack onto the desk so items sit individually.

3. Layered Conceptual Depth

Layer 1: The Intuition — The Custom Sandwich Order

Think of placing an order at a sandwich counter:
  1. Positional Parameters: The bread and the base protein must come first in exact sequence: order("sourdough", "tofu").
  2. Default Parameters: Condiments come pre-selected unless you specify otherwise: sauce="mayo", toasted=True.
  3. *args (Extra Toppings): You can request arbitrary loose toppings without defining individual slots: "olives", "pickles", "jalapenos" are bundled together into a basket.
  4. **kwargs (Custom Prep Instructions): You can pass arbitrary name-value preferences: cut="diagonal", wrap="foil", salt="extra" are collected onto a labelled order slip.

Layer 2: The Invariant Ordering Grammar

Python enforces a single non-negotiable ordering in both function definitions and function calls.

Signature Definition Grammar

Every function header must follow this exact sequential hierarchy:
def func(pos_only, /, standard_pos_or_kw, default_pos_or_kw=val, *args, kw_only, kw_only_default=val, **kwargs):
[1. Positional-Only]   ──► [2. Pos-or-Keyword] ──► [3. Defaults] ──► [4. *args] ──► [5. Keyword-Only] ──► [6. **kwargs]
    (before '/')                                                                     (after '*')
Important
The Golden Call-Site Rule: In any function call, all positional arguments must precede keyword arguments. Writing func(a=1, 2) causes an immediate SyntaxError: positional argument follows keyword argument before execution even begins.

Layer 3: Execution Mechanics — The Mutable Default Argument Trap

Why is the following code considered one of Python's most notorious exam traps?
python
def append_element(val, target_list=[]):
    target_list.append(val)
    return target_list

print(append_element(1)) # Output: [1]
print(append_element(2)) # Output: [1, 2]  <-- NOT [2]!
print(append_element(3)) # Output: [1, 2, 3]

The Underlying Interpreter Architecture

  1. Definition Time vs Call Time: Python executes def statements once when the module or script is loaded, NOT each time the function is called.
  2. Object Creation: When the interpreter encounters target_list=[], it allocates a single list object in memory (e.g. at address 0x7f80) and binds it to the function's __defaults__ tuple.
  3. Shared Persistence: Every subsequent call to append_element() that omits the second argument binds target_list to that exact same list in memory. Modifying target_list mutates the permanent default object stored on the function object itself!
Function Object `append_element`
  ├── __code__: <bytecode>
  └── __defaults__: ([ 1, 2, 3 ],)  <── Persistent list mutated across calls!

The Idiomatic Safe Pattern (Sentinel None)

python
def append_element_safe(val, target_list=None):
    if target_list is None:
        target_list = []  # Creates a fresh list on EACH call
    target_list.append(val)
    return target_list

4. Worked Anatomy: Complex Binding Trace

Let us dissect a mixed signature call step-by-step:

Function Definition

python
def calculate(base, multiplier=2, *deltas, scale=1, **flags):
    total = base * multiplier
    for d in deltas:
        total += d
    total *= scale
    if flags.get("round_result"):
        total = round(total)
    return total

Call Site

python
result = calculate(10, 3, 4, 6, scale=0.5, round_result=True)

Step-by-Step Binding Process

StepFormal ParameterArgument SuppliedBound ValueTypeJustification
1base10 (1st positional)10intBound to 1st positional slot.
2multiplier3 (2nd positional)3intOverrides default value of 2.
3*deltas4, 6 (remaining pos)(4, 6)tupleRemaining positional args packed into a tuple.
4scalescale=0.5 (kwarg)0.5floatExplicit keyword-only match.
5**flagsround_result=True{"round_result": True}dictExtra keyword arguments packed into dict.

Computation

  1. total = 10 * 3 = 30
  2. Iterating deltas: total += 4 (3434), total += 6 (4040)
  3. Scaling: total = 40 * 0.5 = 20.0
  4. Flag check: flags.get("round_result") is True →\to round(20.0) = 20
  5. Returns 20.

5. Non-Examples & The 3 Critical Failure Modes

                         ┌── 1. SyntaxError: Positional Argument Follows Keyword Argument
                         │
Signature Violations ────┼── 2. TypeError: Function Got Multiple Values for Argument
                         │
                         └── 3. TypeError: Missing Required Keyword-Only Argument

1. Positional After Keyword

python
def greet(first, last):
    return f"{first} {last}"

greet(first="Grace", "Hopper")
# SyntaxError: positional argument follows keyword argument
Python syntax prohibits bare positional values once keyword syntax has begun. You cannot switch back to positional notation within the same call.

2. Multiple Values for the Same Argument

python
def process(x, y=10):
    return x + y

process(5, 20, x=50)
# TypeError: process() got multiple values for argument 'x'
Why it fails: The positional argument 5 already bound parameter x. Supplying x=50 attempts to re-bind x, which is illegal.

3. Keyword-Only Argument Omission

python
def configure(*, timeout=30, retries):
    pass

configure(5)
# TypeError: configure() takes 0 positional arguments but 1 was given
configure(retries=3) # Correct!
Why it fails: Parameters listed after a bare * or *args are strictly keyword-only. They can never receive values positionally.

6. Question-Pattern Anatomy (8 Exam Reflexes)

In IITM BS DS Python exams (Quiz 2, Quiz 3, and OPPE), function argument questions follow eight standardized patterns:
#Pattern NameRecognition CueStandard Attack SequenceThe Planted Trap
P1Mutable Default State Leakdef f(x, L=[]): called multiple timesTrack L across calls as a shared, mutating referenceAssuming L resets to [] on every call
P2Positional-Keyword CollisionPositional argument followed by keyword matching 1st parameterCheck if the keyword name duplicates a slot already filled positionallyAssuming keyword overrides positional silently
P3Keyword-Only Bare AsteriskSignature contains bare def f(a, *, b):Verify that parameter b is passed strictly with b=valAnswering with positional evaluation
P4*args Tuple ImmutabilityCode attempts args[0] = x inside functionRecognize that args is packed as a tuple, not a listOverlooking TypeError: 'tuple' object does not support item assignment
P5Call-Site Unpacking (* and **)f(*tuple) or f(**dict)Expand elements into respective positions/keys before bindingTreating the container as a single composite argument
P6Dictionary Key Type Requirementf(**{1: "a", 2: "b"})Keys unpacked with ** must be strings matching parameter namesExpecting numeric keys to work as kwargs
P7Variable Args Absorbing Defaultsdef f(a, b=2, *args) called with f(1, 2, 3)2nd positional binds b; remaining args go to argsBelieving 3 binds to b and args remains empty
P8Passing None vs Omittingdef f(x=5): called as f(None)None is an explicit argument; it overrides the default 5Assuming None defaults back to 5

7. Interactive Attempt-First Checks

Test your prediction reflexes. Write down your predicted output before opening the solutions.
1

Question 1

Type: MCQ | Marks: 1 | Topic: Persistent Mutable Defaults
What will be printed by the following Python program?
python
def collect(item, box=[]):
    box.append(item)
    return len(box)

a = collect("pencil")
b = collect("eraser")
c = collect("ruler", ["notebook"])
d = collect("pen")

print(f"{a}-{b}-{c}-{d}")
MCQ
Persistent Mutable Defaults
3 Unit Assessment
A
1-1-2-1
B
1-2-2-3
C
1-2-1-3
D
1-2-2-1

2

Question 2

Type: NAT | Marks: 1 | Topic: Argument Unpacking & Keyword-Only Calculation
What is the integer value printed by the following code?
python
def score(mult, *vals, offset=10):
    return sum(vals) * mult + offset

data = [2, 3, 5]
ans = score(3, *data, 10, offset=5)
print(ans)
NAT
3 Unit Assessment

3

Question 3

Type: MCQ | Marks: 1 | Topic: Call-site Grammar Violations
Which of the following function calls will raise a SyntaxError before the code runs?
python
def register(id_num, name, role="Student", *courses, notify=True):
    pass
MCQ
Call-site Grammar Violations
3 Unit Assessment
A
register(101, "Aarav", "Tutor", "CS101", notify=False)
B
register(101, name="Aarav", role="Admin")
C
register(101, name="Aarav", "CS101")
D
register(101, "Aarav", notify=True)

Blank-Page Active Recall Challenge

Close this document. Take a blank paper and write:
  1. The general signature rule showing the relative positions of pos, *args, kw_only, and **kwargs.
  2. Explain why def add(x, L=[]): behaves differently than def add(x, L=None): when called multiple times.

8. Next Action & Spacing Protocol

  • Immediate Next Chapter: Week 8: Recursion in Python — Combine parameter passing with recursive call stacks.
  • Active Drill Desk: Visit the Quiz 3 Checkpoint Desk to drill Python predict-the-output questions.
  • Spaced Review Suggestion: Re-attempt the Mutable Default trace (Question 1) in 48 hours to confirm persistent memory reflexes.

Provenance: Authored from scratch adhering to the Learning OS Authoring Cookbook standard (docs/authoring/AUTHORING_COOKBOOK.md). Original imported reference 797 - Function Arguments — Positional, Keyword, Default, Variable.md preserved intact.
Document outline

Keep your place and jump directly to a heading.

Table of contents

No note selected

Open a chapter to see its outline, backlinks, and sources here.