Functions and modules

Arguments, returns, scoping, lambdas, and organizing code into importable modules.

Arguments

def greet(name, greeting='Hello', *extra, punct='!', **opts):
    """Docstring: what this function is for."""
    parts = [greeting, name, *extra]
    sep = opts.get('sep', ' ')
    return sep.join(parts) + punct

greet('Ada')                        # Hello Ada!
greet('Ada', punct='?')             # keyword-only must be named
greet('Ada', 'Hi', punct='.')
FormMeaning
def f(a, b=1)Positional with default
def f(*args)Extra positionals as a tuple
def f(**kwargs)Extra keywords as a dict
def f(*, a)Keyword-only argument
def f(a, /, b)a positional-only
⚠️
Mutable default arguments are evaluated once when the function is defined, then shared by every call. Use None and build inside the body — see the aliasing trap above.

Returning values

def divide(a, b):
    return a / b

q, r = divmod(10, 3)      # multiple return values are a tuple
name, _, score = row      # _ conventionally means 'ignored'

def find(users, uid):
    return None            # explicit absence beats raising for 'not found'

A function with no return gives None. Return early for guard clauses rather than nesting — flatter code reads better.

Scope

Python resolves names with LEGB: Local, Enclosing, Global, Built-in. Assigning inside a function makes a name local unless you declare otherwise.

count = 0

def bump():
    global count     # needed to rebind the module-level name
    count += 1

def make_adder(n):
    def add(x):      # closure over n
        return x + n
    return add

add5 = make_adder(5)
add5(3)   # 8

Modules and imports

# maths.py
def area(r): return 3.14159 * r * r

if __name__ == '__main__':
    print(area(2))          # only when run directly

# consumer
from maths import area
import maths as m
from pathlib import Path
  • The __name__ == '__main__' guard keeps script code from running on import.
  • Prefer importing modules over individual names when several functions share a namespace.
  • Avoid from x import * — it pollutes the namespace and hides where names came from.

FAQ

lambda or def?
Lambdas are limited to a single expression — use them for short callbacks like key=lambda u: u['name']. Anything needing statements, a name, or a docstring belongs in def.
How do I return two things?
Just separate with commas; Python packs them into a tuple. For more than two values, a NamedTuple or dataclass keeps call sites readable.

Errors, files and virtualenvs Python: getting started

Last refreshed 2026-09-17.