The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Define a functiondef greet(name): return f"Hello, {name}!"View examples
Call a functionmessage = greet("Ada")View examples
Set a default valuedef greet(name, punctuation="!"): return f"Hello, {name}{punctuation}"View examples
Pass a keyword argumentmessage = greet(name="Ada", punctuation=".")View examples
Require a positional inputdef ratio(value, total, /): return value / totalView examples
Require a keyword inputdef connect(host, *, timeout=10): return f"{host}:{timeout}"View examples
Create a fresh default listdef collect(value, items=None): items = [] if items is None else items items.append(value) return itemsView examples
Collect positional argumentsdef total(*values): return sum(values)View examples
Collect keyword argumentsdef profile(**fields): return fieldsView examples
Unpack positional valuesresult = total(*[4, 6, 10])View examples
Unpack keyword valuesuser = profile(**{"name": "Ada", "role": "engineer"})View examples
Annotate a functiondef area(width: float, height: float) -> float: return width * heightView examples
Add a docstringdef area(width, height): """Return a rectangle's area.""" return width * heightView examples
Return a valuedef double(number): return number * 2View examples
Return several valuesdef bounds(values): return min(values), max(values)View examples
Pass a callbacklabels = list(map(str.upper, ["draft", "ready"]))View examples
Create a small lambdausers.sort(key=lambda user: user["name"])View examples
Return a closuredef multiplier(factor): return lambda value: value * factorView examples
Wrap a functiongreet = trace(greet)View examples

Functions package behavior behind a clear name and interface. Keep each function focused, make required and optional inputs obvious, avoid shared mutable defaults, and use annotations and docstrings to communicate intent without assuming they enforce runtime types.

Step by step

Detailed examples

01

Define and call a focused function

A def statement creates a function object; its body runs only when the function is called. Parameters receive the supplied arguments, and return hands a result to the caller. Use a descriptive verb-oriented name and keep unrelated side effects outside a calculation function.

Create and call a greeting function
def greet(name):
    return f"Hello, {name}!"

message = greet("Ada")
print(message)
Output
Hello, Ada!
Back to quick reference ↑
02

Design positional and keyword parameters

Defaults make trailing parameters optional, while keyword arguments clarify calls with several similar values. A slash marks preceding parameters as positional-only, and an asterisk marks following parameters as keyword-only. These boundaries can preserve an API's freedom to rename internal parameters or make important options explicit.

Defaults and an explicit keyword call
def greet(name, punctuation="!"):
    return f"Hello, {name}{punctuation}"

message = greet(name="Ada", punctuation=".")
print(message)
Output
Hello, Ada.
Positional-only and keyword-only parameters
def ratio(value, total, /):
    return value / total

def connect(host, *, timeout=10):
    return f"{host}:{timeout}"

print(ratio(3, 4))
print(connect("db.internal", timeout=5))
Output
0.75
db.internal:5

Note: The slash parameter marker requires Python 3.8 or newer.

Back to quick reference ↑
03

Avoid shared mutable default values

Default expressions are evaluated once when the def statement runs, not once per call. A list, dictionary, or set used directly as a default would therefore be shared by every omitted call. Use None as a sentinel and allocate the mutable value inside the function instead.

Allocate one list per omitted call
def collect(value, items=None):
    items = [] if items is None else items
    items.append(value)
    return items

print(collect("alpha"))
print(collect("beta"))
print(collect("gamma", ["existing"]))
Output
['alpha']
['beta']
['existing', 'gamma']
Back to quick reference ↑
04

Collect and unpack flexible arguments

A starred parameter collects extra positional inputs into a tuple, and a double-starred parameter collects extra named inputs into a dictionary. At the call site, the same operators unpack an iterable or mapping. Use flexible signatures when the domain genuinely accepts variable inputs, not to hide a function's required interface.

Collect and unpack positional arguments
def total(*values):
    return sum(values)

result = total(*[4, 6, 10])
print(result)
Output
20
Collect and unpack named fields
def profile(**fields):
    return fields

user = profile(**{"name": "Ada", "role": "engineer"})
print(user)
Output
{'name': 'Ada', 'role': 'engineer'}

Note: Every key unpacked with double star must be a string acceptable as a keyword name for the target call.

Back to quick reference ↑
05

Document intent with annotations and docstrings

Annotations expose metadata for static type checkers, editors, and documentation tools, but Python does not enforce them automatically at runtime. A docstring should state the function's purpose and any important behavior that the signature cannot express clearly.

Annotated and documented area function
def area(width: float, height: float) -> float:
    """Return a rectangle's area."""
    return width * height

print(area(3.5, 2.0))
print(area.__doc__)
Output
7.0
Return a rectangle's area.
Back to quick reference ↑
06

Return and unpack results

A return statement ends the current call immediately. Writing comma-separated return expressions creates one tuple, which a caller can unpack into the same number of targets. A function that reaches the end without return produces None, so make that behavior intentional.

One return value
def double(number):
    return number * 2

print(double(6))
Output
12
Tuple return and unpacking
def bounds(values):
    return min(values), max(values)

lowest, highest = bounds([8, 3, 11, 5])
print(lowest, highest)
Output
3 11
Back to quick reference ↑
07

Pass functions as data

Functions are objects that can be passed to other functions, stored, and returned. Use a named def when behavior needs documentation or several statements; use a lambda for a short expression that is clearest next to the operation consuming it.

Named callback and lambda sort key
labels = list(map(str.upper, ["draft", "ready"]))
users = [{"name": "Grace"}, {"name": "Ada"}]
users.sort(key=lambda user: user["name"])

print(labels)
print(users)
Output
['DRAFT', 'READY']
[{'name': 'Ada'}, {'name': 'Grace'}]
Back to quick reference ↑
08

Capture state and wrap behavior

A closure retains access to names from the enclosing function after that outer call returns. A decorator receives a function and replaces the decorated binding with another callable, often a wrapper. Preserve wrapper metadata with functools.wraps in production decorators so introspection and documentation still identify the original function.

Closure-based multiplier
def multiplier(factor):
    return lambda value: value * factor

double = multiplier(2)
print(double(7))
Output
14
Tracing decorator
from functools import wraps

def trace(function):
    @wraps(function)
    def wrapper(*args, **kwargs):
        print(f"calling {function.__name__}")
        return function(*args, **kwargs)
    return wrapper

@trace
def greet(name):
    return f"Hello, {name}"

print(greet("Ada"))
Output
calling greet
Hello, Ada
Equivalent explicit decorator call
def trace(function):
    def wrapper(*args, **kwargs):
        print(f"calling {function.__name__}")
        return function(*args, **kwargs)
    return wrapper

def greet(name):
    return f"Hello, {name}"

greet = trace(greet)
print(greet("Grace"))
Output
calling greet
Hello, Grace

Note: The @trace form is syntactic sugar for this rebinding and is normally clearer directly above the function definition.

Back to quick reference ↑

Local code tester

Try Python function interfaces

Edit and run the functions locally to practice defaults, keyword-only parameters, callbacks, and return values.

Runs in your browser
Output
Press Run to load Python locally.

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Python Software FoundationMore Control Flow Tools — Defining Functionsdocs.python.org
  2. Python Software FoundationCompound statements — Function definitionsdocs.python.org
  3. Python Software FoundationBuilt-in Functionsdocs.python.org
  4. Python Software Foundationfunctools — Higher-order functions and operations on callable objectsdocs.python.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback