Functions & Modules
Functions help you organize code into reusable pieces. Modules help you split code across files.
Defining Functions
def greet(name: str) -> str:
return f"Hello, {name}!"
result = greet("Alice")
print(result) # "Hello, Alice!"
A function should do one thing and have a clear name.
Parameters and Arguments
Positional and Keyword Arguments
def create_user(name: str, age: int, role: str = "tester") -> dict:
return {"name": name, "age": age, "role": role}
# Positional
user1 = create_user("Alice", 30)
# Keyword
user2 = create_user(name="Bob", age=25, role="developer")
Default Values
def connect(host: str = "localhost", port: int = 5432) -> str:
return f"{host}:{port}"
Never use mutable defaults
Do not use list or dict as default values. Use None instead.
# Bad
def add_item(item: str, items: list = []) -> list: ...
# Good
def add_item(item: str, items: list | None = None) -> list:
if items is None:
items = []
items.append(item)
return items
args and *kwargs
def log_info(*args: str) -> None:
for arg in args:
print(arg)
def build_config(**kwargs: str) -> dict:
return dict(kwargs)
log_info("start", "process", "end")
config = build_config(host="localhost", port="5432")
Return Values
A function can return one or multiple values:
def divide(a: int, b: int) -> tuple[int, int]:
quotient = a // b
remainder = a % b
return quotient, remainder
q, r = divide(10, 3) # q=3, r=1
Lambda Functions
Small, one-line anonymous functions:
square = lambda x: x ** 2
print(square(5)) # 25
users = [{"name": "Bob", "age": 25}, {"name": "Alice", "age": 30}]
sorted_users = sorted(users, key=lambda u: u["age"])
Use lambda sparingly
If the logic is complex, use a regular def function instead.
Modules
A module is a .py file with functions, classes, or variables.
Importing
import json
from pathlib import Path
from typing import Any
Custom Modules
project/
├── utils/
│ ├── __init__.py
│ └── helpers.py
├── tests/
│ └── test_helpers.py
└── main.py
# utils/helpers.py
def format_name(first: str, last: str) -> str:
return f"{first} {last}"
# main.py
from utils.helpers import format_name
print(format_name("Alice", "Smith"))
Packages
A package is a folder with an __init__.py file. It groups related modules.
# utils/__init__.py
from utils.helpers import format_name
__all__ = ["format_name"]
Useful Built-in Functions
| Function | What It Does |
|---|---|
len(x) |
Length of a sequence |
range(n) |
Sequence of numbers |
enumerate(x) |
Index + value pairs |
zip(a, b) |
Pair items from two lists |
map(fn, x) |
Apply function to each item |
filter(fn, x) |
Keep items where function returns True |
sorted(x) |
Return sorted copy |
any(x) |
True if any item is truthy |
all(x) |
True if all items are truthy |
Best Practices
- Keep functions small — one function, one purpose
- Use type hints for parameters and return values
- Prefer pure functions (no side effects) when possible
- Avoid global state — pass data through parameters
- Use
from module import namefor specific imports - Put all imports at the top of the file
- Follow Single Responsibility Principle for modules