Args, Kwargs & Parameters
Parameters and arguments
Section titled “Parameters and arguments”Python distinguishes between parameters (names in the function definition) and arguments (values passed at call time). Python gives you fine-grained control over how callers can supply those values.
Positional and keyword arguments
Section titled “Positional and keyword arguments”By default, every parameter can be supplied positionally or by keyword name.
def connect(host: str, port: int, timeout: int = 30) -> str: return f"{host}:{port} (timeout={timeout}s)"
# Positionalconnect("localhost", 5432)
# Keyword — order does not matterconnect(port=5432, host="localhost")
# Mixed — positional first, then keywordconnect("localhost", port=5432, timeout=60)timeout has a default value of 30, making it optional.
Positional arguments must always come before keyword arguments at the call site.
Variadic positional args: *args
Section titled “Variadic positional args: *args”Prefix a parameter with * to collect any number of positional arguments into a tuple.
def total(*amounts: float) -> float: return sum(amounts)
print(total(10.0, 20.5, 5.0)) # 35.5print(total()) # 0.0Variadic keyword args: **kwargs
Section titled “Variadic keyword args: **kwargs”Prefix a parameter with ** to collect any number of keyword arguments into a dict.
def log_event(event: str, **metadata) -> None: parts = [f"event={event}"] for key, value in metadata.items(): parts.append(f"{key}={value}") print(", ".join(parts))
log_event("login", user_id=42, ip="127.0.0.1")# event=login, user_id=42, ip=127.0.0.1Keyword-only parameters
Section titled “Keyword-only parameters”Any parameter listed after a bare * (or after *args) can only be supplied by keyword — never positionally.
This makes APIs self-documenting and prevents argument order mistakes.
def send_email(to: str, subject: str, *, cc: str = "", bcc: str = "") -> None: print(f"To: {to} | Subject: {subject} | CC: {cc} | BCC: {bcc}")
# Calling send_email("[email protected]", "Hi", "[email protected]") would raise TypeErrorFull parameter order
Section titled “Full parameter order”The order of parameter kinds in a definition must always be:
- Positional-or-keyword (
x,y) *args(or bare*)- Keyword-only (
key=valueafter*) **kwargs
def describe( name: str, *adjectives: str, separator: str = ", ", **extras) -> str: adj_str = separator.join(adjectives) if adjectives else "no adjectives" extra_str = ", ".join(f"{k}={v}" for k, v in extras.items()) result = f"{name}: {adj_str}" if extra_str: result += f" ({extra_str})" return result
print(describe("Python"))print(describe("Python", "fast", "readable"))print(describe("Python", "fast", "readable", separator=" | "))print(describe("Python", "fast", separator=" + ", version="3.11", typed=True))Loading Python runtime (first run only)…