Python
commenting
functions
code documentation
programming best practices

What is the proper way to comment functions in Python?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In Python, the best way to document functions is to use docstrings for behavior and keep inline comments for non-obvious reasoning. Good documentation is not about explaining every line. It is about making intent, inputs, outputs, and failure modes clear to future readers.

Use Docstrings as the Main Contract

For reusable functions, docstrings are the canonical source of usage information. A strong docstring should explain purpose, arguments, return values, and important exceptions.

python
1def normalize_scores(scores: list[float]) -> list[float]:
2    """Scale numeric scores to the range from 0.0 to 1.0.
3
4    Args:
5        scores: Non-empty list of numeric scores.
6
7    Returns:
8        New list with normalized values.
9
10    Raises:
11        ValueError: If the list is empty or all values are equal.
12    """
13    if not scores:
14        raise ValueError("scores must not be empty")
15
16    lo, hi = min(scores), max(scores)
17    if lo == hi:
18        raise ValueError("cannot normalize constant values")
19
20    return [(s - lo) / (hi - lo) for s in scores]

This format works well in IDE tooltips and generated docs, and it reduces the need to inspect implementation details.

Inline Comments Should Explain Why

Inline comments are useful when the reasoning is not obvious from code itself. Avoid comments that simply restate the line below.

python
1def retry_delays(max_attempts: int) -> list[float]:
2    delays = []
3    for i in range(max_attempts):
4        # Cap growth early to protect downstream services from burst retries.
5        delay = min(0.1 * (2 ** i), 2.0)
6        delays.append(delay)
7    return delays

If you find many inline comments describing what code does, prefer refactoring into clearer names and smaller helpers.

Keep Documentation and Type Hints Aligned

Function signatures, type hints, and docstrings should describe the same contract. Drift between them creates hard to diagnose bugs and broken assumptions.

python
1def fetch_payload(url: str, timeout_seconds: float, max_retries: int) -> bytes:
2    """Fetch response payload bytes with bounded retries.
3
4    Args:
5        url: Endpoint to request.
6        timeout_seconds: Per attempt timeout.
7        max_retries: Number of retries after first failure.
8    """
9    raise NotImplementedError

When signature changes, update docstring in the same commit.

Document Public APIs More Than Private Helpers

Not every private helper needs a long docstring. Focus effort where readers need it most:

  • Public modules and library entry points.
  • Business critical decision logic.
  • Functions with non-trivial side effects.

A simple private helper with obvious naming may need no comment at all. Over-documentation can make code noisy and harder to scan.

Add Executable Examples Through Tests

Documentation becomes reliable when examples are backed by tests. If your docstring states behavior, create a matching unit test.

python
1def clamp(value: int, low: int, high: int) -> int:
2    """Return value limited to the inclusive range low through high."""
3    return max(low, min(value, high))
4
5
6def test_clamp_examples() -> None:
7    assert clamp(5, 1, 10) == 5
8    assert clamp(-3, 1, 10) == 1
9    assert clamp(99, 1, 10) == 10

This keeps docs and implementation from drifting apart.

Choose One Docstring Style

Teams generally pick one style such as Google style, NumPy style, or reStructuredText. Any style is fine if it is consistent.

Consistency benefits:

  • Predictable reading flow in code reviews.
  • Better auto-generated documentation.
  • Easier linting and automated checks.

Use one linter configuration and enforce it across repositories to avoid mixed conventions.

Common Pitfalls

  • Writing comments for obvious statements instead of clarifying intent.
  • Skipping exception behavior in public function docs.
  • Letting docstrings become stale after refactors.
  • Using vague function names and compensating with long comments.
  • Mixing incompatible docstring styles within one codebase.

Summary

  • Use docstrings as the primary documentation for Python functions.
  • Reserve inline comments for non-obvious design decisions.
  • Keep signatures, type hints, tests, and docstrings synchronized.
  • Prioritize documentation quality on public and business critical APIs.
  • Consistent style and review discipline keep comments trustworthy.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.