Home/Python/Functions

Functions

Parameters, return values, scope, and reusable behavior

Parameters and return values

A function names a reusable operation. def creates the function; its body runs when called. Parameters receive the caller's objects. return supplies a result; reaching the end returns None. Printing does not return a value to the caller.

Positional arguments match by position; keyword arguments match by name. Defaults make arguments optional. A * in a signature makes subsequent parameters keyword-only.

Python
def request_headers(base, *, request_id):
    result = dict(base)
    result["X-Request-ID"] = request_id
    return result

defaults = {"Accept": "application/json"}
headers = request_headers(defaults, request_id="r-17")
print(headers["X-Request-ID"])  # r-17
print("X-Request-ID" in defaults)  # False

Copying base prevents changes to its entries. This is a shallow copy: nested mutable values would remain shared. The keyword-only request_id makes the option explicit at the call site.

Scope and callbacks

Local names belong to a call. Functions can read enclosing and module names, but assignment normally creates a local binding. Prefer explicit parameters over changing global state.

Rebinding a parameter does not rebind the caller's variable; mutating its list or dictionary changes the shared object. State whether a function mutates its input or returns independent data.

Functions are values: they can be stored, passed as callbacks, or returned. Sorting keys and transformation APIs use callbacks to accept caller-defined behavior.

Gotchas

Default expressions are evaluated when the definition executes, not on each call:

Python
def tagged(label, tags=[]):
    tags.append(label)
    return tags

first = tagged("alpha")
second = tagged("beta")
print(first is second)  # True
print(first)  # ['alpha', 'beta']

Both calls use the same default list. For independent storage, default to None and create a list inside the call. If None is a valid supplied value, use a distinct sentinel for omission. Immutable defaults avoid mutation but may need conversion before editing.

Document callback call counts, failures, and ownership. Pass dependencies as arguments so they can be substituted. Extract functions around meaningful rules; excessive fragmentation can make a simple operation harder to follow.

Put it into practice

Implement the exercise in a full-screen workspace, then run its tests.

Open practice
Next lessonErrors and exceptions