Every well-written Python function is built from four core ingredients: name, parameters, body, and return value. Get these right, and your functions become clear, reusable, testable, and maintainable. In 2026, modern functions also include type hints and docstrings as essential parts of the recipe.
Here’s a complete, practical breakdown of the basic ingredients of a function — with real examples and best practices used by professionals today.
1. Function Name
- Should be lowercase with underscores (
snake_case) - Descriptive — tells what the function does
- Starts with a verb (action-oriented):
calculate_total,fetch_user_data,validate_email - Avoid vague names:
process,do_stuff,func1
2. Parameters (Inputs)
Parameters let callers pass data into the function. They can be required, optional (defaults), positional, keyword, variable (*args, **kwargs), or restricted (positional-only /, keyword-only *).
def calculate_total(
items: list[float], # required positional
tax_rate: float = 0.08, # optional (default)
/, # ?? end positional-only ??
*, # ?? start keyword-only ??
discount: float = 0.0
) -> float:
...
3. Function Body (The Logic)
This is where the actual work happens: computations, loops, conditionals, calls to other functions, side effects (printing, file I/O, database writes), etc.
- Keep it focused — one clear responsibility per function
- Use meaningful variable names
- Avoid deep nesting — prefer early returns or guard clauses
4. Return Value (Output)
The return statement sends data back to the caller. A function can return:
- nothing (None — implicit or explicit)
- one value
- multiple values (tuple)
- complex objects (dict, list, custom class)
def divide_and_remainder(x: float, y: float) -> tuple[float, float]:
"""Return quotient and remainder."""
if y == 0:
raise ValueError("Division by zero")
return x / y, x % y
q, r = divide_and_remainder(10, 3)
print(f"Quotient: {q:.2f}, Remainder: {r}") # Quotient: 3.33, Remainder: 1.0
Putting It All Together (Real-World Example)
def process_order(
items: list[float], # required positional
customer_id: int, # required positional
/, # positional-only boundary
discount: float = 0.0, # optional keyword/positional
*, # keyword-only boundary
tax_rate: float = 0.08,
currency: str = "USD"
) -> dict:
"""
Process a shopping cart order.
Args:
items: List of item prices
customer_id: Unique customer identifier
discount: Optional discount percentage (0.0–1.0)
tax_rate: Sales tax rate (default 8%)
currency: Currency code (default USD)
Returns:
Dictionary with subtotal, total, and status
Raises:
ValueError: If discount is invalid
"""
if discount < 0 or discount > 1:
raise ValueError("Discount must be between 0 and 1")
subtotal = sum(items)
discounted = subtotal * (1 - discount)
total = discounted * (1 + tax_rate)
return {
"subtotal": round(subtotal, 2),
"total": round(total, 2),
"currency": currency,
"status": "success" if items else "empty"
}
# Example calls
order = process_order([100, 50], 12345, discount=0.1)
print(order)
# {'subtotal': 150.0, 'total': 145.8, 'currency': 'USD', 'status': 'success'}
Best Practices & Modern Tips (2026 Edition)
- Type hints — always use them — makes code self-documenting and IDE/mypy-friendly
- Docstrings — include description, args, returns, raises, examples — use Google or NumPy style
- Name clearly — verb + noun (
fetch_user_data,validate_email) - Single responsibility — one function = one job — keep body short (ideally <20 lines)
- Defaults & boundaries — use
/and*to enforce positional/keyword intent - Pitfall — mutable defaults — never do
def func(lst=[])— useNone+ check - Modern tip — use
typing.Self(3.11+) in class methods,@overloadfor complex signatures
Conclusion
A great function is defined by four ingredients: a clear name, thoughtful parameters, focused body, and meaningful return value. In 2026, add type hints, docstrings, and parameter boundaries to make functions self-explanatory and robust. Whether you're writing small helpers or complex business logic, these elements turn good code into excellent code.
Next time you write a function — start with its name and signature. Get those right, and the rest flows naturally.