Need to add an optional note to a function without changing every existing call? Give the parameter a default value. Python uses it when the caller omits the corresponding argument; callers can still supply a different value. Choose defaults for values that stay the same in most calls, so the usual call remains short and readable. section 6.1.2 section 6.6
def complete_task(task, note=""):
task.status = "completed"
task.note = note
print(f"{task.title}'s status: completed; note: {note}")
With `note=""`, `complete_task(task)` still works, while `complete_task(task, "Finished early")` supplies a note. The default avoids repeated empty-string arguments and preserves existing calls. section 6.1.2
Defaults are familiar in the standard library. `numbers.sort()` uses its usual sorting behavior because `key` defaults to `None` and `reverse` defaults to `False`; `numbers.sort(reverse=True)` overrides the latter to sort in descending order. Here `reverse` is keyword-only, so it must be named in the call. section 6.1.1
Do not use an empty list as a default when each call needs its own list. A default object is created when the function is defined, not anew each time the argument is omitted. If the function mutates that list, later calls see earlier changes. section 6.1.3
Listing 6.1 Using functions with mutable default arguments
task0 = Task("Homework", "Physics and math", 5)
task1 = Task("Fishing", "Fishing at the lake", 3)
work_tasks = complete_task(task0)
play_tasks = complete_task(task1)
print("Work Tasks:", work_tasks)
print("Play Tasks:", play_tasks)
# output the following lines:
Work Tasks: ['Homework', 'Fishing']
Play Tasks: ['Homework', 'Fishing']
Two calls that omit `grouped_tasks` produce the same list containing both task titles—not separate work and play lists. section 6.1.3
Listing 6.3 Using None as the default value for mutable parameters
def complete_task(task, grouped_tasks=None):
task.status = "completed"
if grouped_tasks is None: #1
grouped_tasks = []
grouped_tasks.append(task.title)
return grouped_tasks
complete_task.__defaults__
# output: (None,)
Use `None` as the default and create a list inside the function when `grouped_tasks is None`. Each omitted argument then gets a new list; callers can still pass one explicitly. section 6.1.3
A fallback in `dict.get` is related but distinct: `urgencies.get("Homeworks", "N/A")` returns `"N/A"` when the key is absent, and omitting the fallback returns `None`. This is useful when optional `**kwargs` are read as a dictionary. By contrast, `dict.setdefault` inserts a missing key with its fallback, so prefer `get` when that side effect is unwanted. section 3.4.4 section 3.4.5
Defaults also make constructors easier to call. In a data class, an annotated field can have a default, such as `tip_amount: float = 0`; omitting it fills in zero. Put fields without defaults before fields with defaults. Because a data-class subclass inherits its superclass’s fields first, a defaulted superclass field also constrains the subclass’s field order. section 9.2.2 section 9.2.4
When adding a type hint to a defaulted parameter, write the hint before the default, as in `multiplier: int = 1`. A default is less suitable when the commonly repeated arguments differ by project; partial functions are presented as an alternative for that pattern. section 6.3.3 section 7.5



















