Skip to main content

Functions

A function groups instructions that you can call with input values. Parameters name those inputs in the definition; arguments are the values supplied when calling it. The function returns a result or raises an exception. Below, clamp keeps a number within the interval from lower to upper: clamp(12, 0, 10) returns 10. With strict=True, an out-of-range value raises an exception instead. Annotations such as value: float describe expected input types, and -> float describes the expected return type; they do not enforce those types at runtime.

def clamp(value: float, lower: float, upper: float, *, strict: bool = False) -> float:
if lower > upper:
raise ValueError("lower must not exceed upper")
if strict and not lower <= value <= upper:
raise ValueError("value is outside the interval")
return min(max(value, lower), upper)

The * makes following parameters keyword-only, which is useful for behavioral flags whose meaning would be unclear positionally.

Parameter kinds​

Python supports positional-only parameters before /, positional-or-keyword parameters, variadic positional *args, keyword-only parameters after *, and variadic keyword **kwargs. Use the narrowest interface that communicates intent; forwarding arbitrary arguments weakens discoverability.

Defaults are evaluated once​

Default expressions run when the function is defined, not on every call. Avoid shared mutable defaults:

def collect(item: str, bucket: list[str] | None = None) -> list[str]:
if bucket is None:
bucket = []
bucket.append(item)
return bucket

Return and ownership​

Reaching the end without return returns None. Returning multiple comma- separated values constructs a tuple. Document whether a function mutates an argument, returns a new object, performs I/O, or retains references.

Annotations and docstrings​

Annotations communicate intended types to readers and tools; the interpreter does not generally enforce them. A concise docstring should explain behavior, important invariants, raised exceptions, and surprising side effects rather than repeat the signature.

Design rules​

  • Separate pure calculation from I/O when practical.
  • Prefer explicit result values over printing inside reusable logic.
  • Raise specific exceptions at the boundary where invalid state is recognized.
  • Keep a function at one useful level of abstraction.

Local scope and shared arguments​

Under Python's name resolution rules, ordinary function code searches local names, enclosing function scopes, the module, then built-ins. Assignment anywhere in a function normally makes that name local throughout the function. Reading it before its local assignment raises UnboundLocalError, even if a module variable has the same name. global targets the module binding; nonlocal targets an existing enclosing function binding. Neither is needed merely to read a name or mutate a referenced list.

def modify(items):
items.append(2) # mutate the caller's object
items = [99] # rebind only this local name
return items

numbers = [1]
assert modify(numbers) == [99]
assert numbers == [1, 2]
assert collect("a") == ["a"]
assert collect("b") == ["b"]
bucket = []
assert collect("c", bucket) is bucket
assert clamp(12, 0, 10) == 10
assert clamp(5, 0, 10, strict=True) == 5

The clamp example assumes finite, ordered numeric inputs; it is not a validator for NaN or arbitrary objects. Calling clamp(5, 0, 10, True) raises TypeError because strict is keyword-only. Missing required arguments, duplicate argument bindings, and unexpected keywords also raise TypeError. At a call site, *values unpacks positional arguments and **options unpacks a mapping of keyword arguments. A def binds a function object without executing its body; this also allows functions to be passed as values or returned from other functions.

In Python Tutor, call collect twice with its None default, then twice with the same explicit list. Follow the local parameter’s reference on each call to distinguish a fresh default-created list from intentionally shared caller state.

Source​

Explore connectionsOpen network