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 alist
where adict
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.