Skip to content

Functions

Use def followed by the function name, a parameter list in parentheses, and a colon. The body is indented 4 spaces. Type hints are optional but strongly recommended — they document intent and enable static analysis.

def greet(name: str, greeting: str = "Hello") -> str:
"""Return a greeting string for the given name."""
return f"{greeting}, {name}!"
print(greet("Alice")) # Hello, Alice!
print(greet("Bob", greeting="Hi")) # Hi, Bob!

The second parameter has a default value — callers may omit it. Default values are evaluated once at function definition time, not at call time.

Python has four kinds of parameters:

def demo(pos, /, normal, *, kw_only):
print(pos, normal, kw_only)
demo(1, 2, kw_only=3) # OK
demo(1, normal=2, kw_only=3) # OK
  • Positional-only (before /): cannot be passed by keyword.
  • Normal: positional or keyword.
  • Keyword-only (after *): must be passed by keyword.

A function can return any number of values by separating them with commas. Python packs them into a tuple automatically.

def min_max(numbers: list) -> tuple:
"""Return (minimum, maximum) of a list."""
return min(numbers), max(numbers)
low, high = min_max([3, 1, 4, 1, 5, 9])
print(f"min={low}, max={high}") # min=1, max=9

Tuple unpacking on the left side of the assignment distributes the returned values into separate variables.

A docstring is a string literal placed immediately after the def line. It documents what the function does, its parameters, and what it returns. Access it via help(fn) or fn.__doc__.

def add(a: int, b: int) -> int:
"""Return the sum of a and b.
Args:
a: First operand.
b: Second operand.
Returns:
The integer sum.
"""
return a + b

Python resolves names in four scopes, searched in order:

  1. Local — inside the current function.
  2. Enclosing — any enclosing function (for nested functions).
  3. Global — the module level.
  4. Built-in — Python’s built-in names (len, print, etc.).
x = 10 # global
def outer():
y = 20 # enclosing
def inner():
z = 30 # local
return x + y + z # finds x globally, y in enclosing, z locally
return inner()
print(outer()) # 60

Use global name to rebind a module-level variable from inside a function. Use nonlocal name to rebind a variable from an enclosing (non-global) scope.

def greet(name: str, greeting: str = "Hello") -> str:
"""Return a greeting string."""
return f"{greeting}, {name}!"
def min_max(numbers: list) -> tuple:
"""Return (minimum, maximum) of a list."""
return min(numbers), max(numbers)
x = 10
def outer():
y = 20
def inner():
z = 30
return x + y + z
return inner()
print(greet("Alice"))
print(greet("Bob", greeting="Hi"))
low, high = min_max([3, 1, 4, 1, 5, 9])
print(f"min={low}, max={high}")
print(f"LEGB sum: {outer()}")
def no_return():
pass
result = no_return()
print(f"no_return() gives: {result}")
What does a Python function return if it has no `return` statement?
Given `def f(a, b=5): ...`, which call is valid?
In the LEGB rule, what does 'E' stand for?
What is the result of `low, high = min_max([3, 1, 4])`?