Functions — *args, **kwargs & Keyword-Only Args
Packing and unpacking, parameter ordering rules, keyword-only arguments, and call-site unpacking
Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.
UpgradeKnowledge Debt detected
You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.
Explanation
*args and **kwargs — packing:** ``python def show(*args, **kwargs): print(args) # tuple of positional args print(kwargs) # dict of keyword args show(1, 2, 3, name='Alice', age=30) # (1, 2, 3) # {'name': 'Alice', 'age': 30}
Parameter ordering rule (must follow this exactly): ``python def f(positional, *args, keyword_only, **kwargs): pass # 1. Regular positional params # 2. *args (captures extra positionals) # 3. Keyword-only params (after * — MUST be passed by name) # 4. **kwargs (captures extra keywords)
Keyword-only arguments — forcing callers to be explicit: ``python def connect(host, port, *, timeout=30, retries=3): # ^ the bare * means everything after is keyword-only pass connect('localhost', 8080, timeout=5) # OK connect('localhost', 8080, 5) # TypeError — timeout must be named
Unpacking at call site:
python nums = [1, 2, 3] print(*nums) # same as print(1, 2, 3) config = {'host': 'localhost', 'port': 8080} connect(**config) # same as connect(host='localhost', port=8080)
Examples
Practical use: wrapper function
*args/**kwargs in wrappers/decorators must pass through to the original function
import time
def timer(func):
def wrapper(*args, **kwargs): # accepts ANYTHING the wrapped fn accepts
start = time.time()
result = func(*args, **kwargs) # passes everything through
print(f"{func.__name__} took {time.time()-start:.3f}s")
return result
return wrapper
@timer
def slow(n, *, label='result'):
time.sleep(0.1)
return f"{label}: {n}"
print(slow(42, label='answer'))How well did you understand this?
Next in Python Core
Closures & Variable Capture