Functions in Python
Functions are first‑class objects defined with def; they can be passed, returned, and stored in data structures.
Defining functions
Parameters are positional by default; use annotations for documentation and tooling.
def add(a: int, b: int) -> int:
return a + b
Docstrings document behavior.
def greet(name: str) -> str:
"""Return a friendly greeting for the given name."""
return f"Hello, {name}!"
Default and keyword arguments
Defaults are evaluated at definition time; use None sentinels for mutable defaults.
def power(x, exp=2):
return x ** exp
from typing import Optional, List
def append_safe(item: int, bucket: Optional[List[int]] = None) -> List[int]:
bucket = [] if bucket is None else bucket
bucket.append(item)
return bucket
*args and **kwargs
Collect extra positional and keyword arguments.
def log(event, *args, **kwargs):
print(event, args, kwargs)
Keyword‑only and positional‑only
Force keywords or positional with * and /.
def config(host, /, *, port=80):
return host, port
Returning multiple values
Python returns tuples; unpack on the caller side.
def divmod_(a, b):
return a // b, a % b
q, r = divmod_(7, 3)
Lambdas and function objects
Lambdas create small anonymous functions; functions are objects with attributes like __name__.
square = lambda n: n*n
Prefer def for readability, especially with complex logic.
Closures
Inner functions capture names from enclosing scopes.
def make_counter():
n = 0
def inc():
nonlocal n
n += 1
return n
return inc
Decorators (preview)
Wrap functions to add behavior (logging, caching). See the Decorators section for details.
Summary
- Use annotations and docstrings to clarify intent
- Avoid mutable default arguments; prefer
Nonesentinels - Master
*args/**kwargs, keyword‑only, and positional‑only for ergonomic APIs