Skip to Content
PythonDefining FunctionsBest Practices & Tooling

Function Best Practices & Tooling

Writing a function that works is only the first step. Writing a function that is reliable, readable, maintainable, and easy to debug is what separates professional code from a simple script. This guide covers the essential best practices and tools that will help you write high-quality Python functions.

Core Design Principles

Good functions are like good tools: they are simple, do one job well, and are easy to understand.

Single Responsibility Principle (SRP)

A function should do one thing, and do it well. If your function description includes the word “and” (e.g., “it validates the data and writes it to a file”), it’s a sign that it might be doing too much.

Bad: A function that does everything.

def process_user_data(data): # 1. Validates data if not data.get("name") or not data.get("email"): print("Error: Missing data") return # 2. Saves to database print(f"Saving {data['name']} to database...") # 3. Sends an email print(f"Sending welcome email to {data['email']}...")

Good: Split into separate, focused functions.

def validate_user(data): if not data.get("name") or not data.get("email"): raise ValueError("User data is incomplete.") def save_user_to_db(user): print(f"Saving {user['name']} to database...") def send_welcome_email(email): print(f"Sending welcome email to {email}...") # Now you can compose them user_data = {"name": "Alice", "email": "alice@example.com"} try: validate_user(user_data) save_user_to_db(user_data) send_welcome_email(user_data["email"]) except ValueError as e: print(e)

Robust Error Handling

Don’t let your functions fail silently. Use Python’s exception system to signal errors clearly.

Pyground

Create a `divide` function that raises specific errors for invalid input.

Expected Output:


5.0
An error occurred: Both numerator and denominator must be numbers.

Output:

Documentation with Docstrings

Every function you intend to reuse should have a docstring explaining its purpose, arguments, and return value.

Pyground

Write a function with a Google-style docstring.

Expected Output:

Docstring: Calculates compound interest.

  Args:
      principal (float): The initial principal amount.
      rate (float): The annual interest rate (as a decimal, e.g., 0.05 for 5%).
      time (int): The number of years the money is invested for.
      n (int, optional): The number of times that interest is compounded per year. 
                         Defaults to 1.

  Returns:
      float: The total amount after compound interest.
  

Output:

Essential Tooling

Leverage automated tools to maintain code quality.

  • Linters (Ruff, Flake8, Pylint): These tools analyze your code for style violations (e.g., line length, variable naming), programming errors (e.g., unused variables), and code complexity. They are like a grammar checker for your code.
  • Type Checkers (Mypy): If you use type hints (name: str), mypy can statically analyze your code to find type-related bugs before you even run it, like passing a list where a dict is expected.
  • Testing Frameworks (pytest): pytest is the standard for testing in Python. It makes writing small, readable tests easy.

Most modern code editors can integrate these tools to give you real-time feedback as you type.

Last updated on