Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 5.2 — Positional, Keyword and Default Arguments
Python · Example 3 of 3

A realistic case: building an API request

Real code builds requests with sensible defaults. The first function shares one headers dict between calls and leaks. The second uses None, copies what the caller gave it, and leaves the caller's dict alone.

Python can match call arguments to parameters by position, by name (keyword arguments), or fill in missing ones from defaults. Defaults are evaluated once when the function is defined, which makes a mutable default such as [] a classic trap.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 6 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Write net_price(price, discount=0.0, tax=0.18) that returns price * (1 - discount) * (1 + tax) rounded to 2 places. Print net_price(1000), then the price with a 10% discount (name the argument), then with no tax, then net_price(tax=0.05, price=200) to show that keyword order is free.

02

Write add_tag(tag, tags=None) that appends tag to the list and returns it, using the None fix. Call it twice and show that the second result does not contain the first tag.

03

Write shout(text, times=1, mark="!") that returns the text in capitals followed by the mark repeated times times. Call it with only text, then with times=3.

Explain it without notes

01

Explain the mutable default argument trap and how to avoid it.

02

Which orderings of positional and keyword arguments are allowed in a call, and why?

03

Why must parameters with defaults come after parameters without?

04

When would you prefer keyword arguments over positional ones in a call?

A realistic case: building an API request
Sign in to run this example in your browser.

Expected output

{'X-Call-0': '/users'}
{'X-Call-0': '/users', 'X-Call-1': '/orders'}
{'method': 'GET', 'path': '/users', 'headers': {'Accept': 'application/json'}, 'timeout': 10}
{'method': 'POST', 'path': '/orders', 'headers': {'Accept': 'application/json'}, 'timeout': 30}
{'Authorization': 'Bearer token', 'Accept': 'application/json'}
caller's dict unchanged: {'Authorization': 'Bearer token'}