Default Arguments, *args, and **kwargs in Python: Dynamic Parameter Architecture
In basic programming, functions require an exact, rigid number of inputs. However, real-world systems need flexibility: the built-in print() function, for example, can accept 1, 5, or 50 arguments; mathematical functions need to sum arbitrary lists of numbers; and configuration parsers must accept varying metadata tags without hardcoding 20 separate parameters.
To enable dynamic and extensible interfaces, Python provides three mechanisms:
1
Default Parameters: Fallback values used when the caller omits an argument.
2
*`args` (Arbitrary Positional Arguments): Packs an unspecified number of positional values into a tuple**.
3
`kwargs` (Arbitrary Keyword Arguments): Packs an unspecified number of named parameters into a dictionary**.
Real-World Analogy: The Kirana Grocery Sack & Special Delivery Instructions
Visual Architecture Blueprint
+-------------------------------------------------------------------------------+
| DYNAMIC ARGUMENT REAL-WORLD ANALOGIES |
+-------------------------------------------------------------------------------+
1. DEFAULT PARAMETERS (Standard Milk Packet):
- At a local Mother Dairy booth:
`def order_milk(pouches=1, brand="Full Cream"):`
- If you just ask "Bhaiya, give milk", the clerk hands you 1 pouch of
Full Cream by default. If you need 4 pouches of Cow Milk, you override
the default: `order_milk(4, "Cow Milk")`.
2. *args (The Assorted Vegetable Sack):
- At a Sabzi Mandi (vegetable market), you hand the vendor an empty burlap sack:
vendor tosses in tomatoes, potatoes, ginger, green chilies, coriander.
- The vendor doesn't know in advance how many vegetables you bought.
All assorted loose items are bundled together into ONE unified sack (`tuple`).
3. **kwargs (Delivery App Metadata Instructions):
- When placing a Swiggy / Zepto order, there is an arbitrary instruction box:
`drop_at="Doorstep"`, `call_guard=True`, `gate_pass_code=7890`
- Every customer enters different keys and values.
The delivery app captures all these key-value pairs into a single
metadata sheet (`dictionary`).
+-------------------------------------------------------------------------------+
Visual Architecture: The Argument Packing Pipeline
In Python, default arguments are evaluated once at function definition time, NOT each time the function is called. The exact same list object in memory is reused across every subsequent invocation!
When a parameter is prefixed with a single asterisk * (conventionally named *args), Python collects all surplus positional arguments passed to the function into a tuple:
27print(f" Grand Total: Rs {inv2['grand_total']:,.2f}")
Output:
1Audit Invoice #INV-001 -> Scanned 2 items.
2 Grand Total: Rs 708.00
3
4Audit Invoice #INV-002 -> Scanned 5 items.
5 Grand Total: Rs 2,091.02
4. Variable Keyword Arguments: **kwargs
When a parameter is prefixed with a double asterisk ** (conventionally named **kwargs), Python collects all surplus keyword arguments passed into the function into a dictionary:
8# connect_db(**config) --> Equivalent to connect_db(host="localhost", port=5432, timeout=30)
7. Do's and Don'ts Best Practices
Best Practice (DO)
Dangerous Anti-Pattern (DON'T)
DO use None as the default value for mutable arguments (lists, dicts, sets).
DON'T use empty lists def func(x=[]) or dicts def func(x={}) as default values!
DO place parameters with default values after mandatory positional parameters.
DON'T place mandatory positional parameters after default parameters (SyntaxError: non-default argument follows default argument).
DO use *args when building mathematical reducers or formatting wrappers.
DON'T overuse **kwargs as a substitute for explicitly documented function signatures.
Quick Revision Summary
Default arguments allow callers to omit parameters, falling back to a pre-set value.
Never use mutable defaults ([], {}); always use default=None and initialize the container inside the function body.
*`args` captures surplus positional arguments into an immutable tuple**.
`kwargs` captures surplus keyword arguments into a mutable dictionary**.
Parameter order in function definitions must be: positional -> default -> *args -> keyword-only -> **kwargs.
The prefix operators * and ** can also be used at the call-site to unpack lists and dictionaries into function arguments.
Interactive Quiz• Knowledge Check
Practice Quiz
1. What data structure does Python use to pack arguments collected by *args?
A. List B. Tuple C. Dictionary D. Set
Answer: B
2. What data structure does Python use to pack keyword arguments collected by **kwargs?
A. List B. Tuple C. Dictionary D. Ordered Set
Answer: C
3. What will be printed by the following code?
1defappend_number(num, num_list=[]):
2 num_list.append(num)
3return num_list
4
5append_number(1)
6append_number(2)
7print(append_number(3))
A. [3] B. [1, 2, 3] C. [2, 3] D. TypeError
Answer: B
4. What is the correct order of parameters in a Python function definition?
A. *args, positional, **kwargs, defaults B. positional, defaults, *args, **kwargs C. **kwargs, *args, defaults, positional D. defaults, positional, *args, **kwargs
Answer: B
5. If payload = {"user": "Kavita", "role": "Admin"}, how can you unpack this dictionary into keyword arguments when calling setup_account(user, role)?
A. setup_account(*payload) B. setup_account(**payload) C. setup_account(&payload) D. setup_account(payload...)
Answer: B
Practice Challenge: Multi-Vendor Marketplace Order Logger & Audit Dispatcher
Build a flexible order dispatcher for an Indian multi-vendor e-commerce marketplace (Tata Neu / ONDC Network).
The dispatch function must handle dynamic inputs: create_marketplace_order(vendor_name, delivery_state="Maharashtra", *item_prices, **order_metadata)
Requirements:
1
vendor_name: Standard mandatory positional string.
2
delivery_state: Default string parameter defaulting to "Maharashtra".
3
*item_prices: Arbitrary number of item prices packed into a tuple.