Friday, June 6, 2025

Python Best Practices: Type Hints, Docstrings, and Doctests Explained with Examples


 In modern Python development, writing clean, maintainable, and well-documented code is not just a luxury—it's essential. Three important features that help with this are type hints, docstrings, and doctests.

In this guide, you’ll learn what they are, why they matter, and how to use them together effectively—with practical examples.


๐Ÿง  Why These Practices Matter

When you're writing Python code—especially for real-world projects or sharing your work—clarity is everything. Here’s how each of these practices contributes:

  • Type hints make your code easier to understand and debug.

  • Docstrings tell others (and your future self) what the code does.

  • Doctests provide a simple way to validate code examples directly from the documentation.


✅ Type Hints (Type Annotations)

Type hints allow you to explicitly declare the expected types for variables, function parameters, and return values. Python is dynamically typed, so type hints don’t enforce rules at runtime—but they do help with code clarity, IDE autocomplete, and static analysis tools like mypy or Pyright.

๐Ÿ“Œ Syntax:

def add(a: int, b: int) -> int:
    return a + b


๐ŸŽฏ Benefits:

  • Easier debugging

  • Better editor support

  • Fewer runtime surprises

๐Ÿ›  Example:

def is_even(n: int) -> bool:
    return n % 2 == 0



✅ Docstrings

A docstring is a string literal placed right after the definition of a function, class, or module. It's used to describe what the code does, including its inputs and outputs.

๐Ÿ“Œ Format (Google style or reStructuredText is common):


def greet(name: str) -> str:
    """
    Returns a personalized greeting.

    Args:
        name (str): The name of the person.

    Returns:
        str: A greeting message.
    """
    return f"Hello, {name}!"


✨ Best Practices:

  • Always write a docstring for public functions and classes.

  • Be concise but descriptive.

  • Include parameter types and return types if not using type hints.


✅ Doctests

Doctests are examples embedded in docstrings that act as test cases. You can run them using Python’s built-in doctest module to verify that your code behaves as expected.

๐Ÿ“Œ How to write a doctest:

def square(x: int) -> int:
    """
    Returns the square of a number.

    Args:
        x (int): A number to square.

    Returns:
        int: The square of the number.

    Examples:
        >>> square(3)
        9
        >>> square(-4)
        16
    """
    return x * x


▶️ Running Doctests

Add this block to the bottom of your Python script:

if __name__ == "__main__":
    import doctest
    doctest.testmod()


Then run the script as usual. If all tests pass, it’ll be silent. If not, you’ll see which examples failed.


๐Ÿงช Complete Example: All Three in Action

def factorial(n: int) -> int:
    """
    Returns the factorial of a non-negative integer.

    Args:
        n (int): A non-negative integer.

    Returns:
        int: Factorial of the input number.

    Raises:
        ValueError: If n is negative.

    Examples:
        >>> factorial(0)
        1
        >>> factorial(5)
        120
    """
    if n < 0:
        raise ValueError("Input must be non-negative")
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result


if __name__ == "__main__":
    import doctest
    doctest.testmod()



๐Ÿงฐ Tools That Work Well with These Practices

Tool

Purpose

mypy

Static type checker for Python

pylint

Code quality and linting

doctest

Runs doctests in docstrings

Sphinx

Builds documentation from docstrings


๐Ÿ“˜ Final Thoughts

Combining type hints, docstrings, and doctests makes your code:

  • Easier to read

  • Easier to test

  • Easier to collaborate on

  • More professional and production-ready

Even if you're writing code just for yourself today, adopting these best practices early builds the discipline needed for writing robust, clean, and shareable Python code.

AI Course

No comments:

Search This Blog