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='.')| Form | Meaning |
|---|---|
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) # 8Modules 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.
Related
Errors, files and virtualenvs Python: getting started
Last refreshed 2026-09-17.