Readable code is maintainable code. Python’s community follows PEP 8 — the official style guide — and uses docstrings to document modules, classes, and functions.

PEP 8 Essentials

Indentation and Line Length

  • Use 4 spaces per indentation level (never tabs)
  • Limit lines to 79 characters (code) or 72 (docstrings/comments)
  • Use blank lines to separate functions and classes
  # Good
def calculate_total(items, tax_rate=0.08):
    subtotal = sum(item.price for item in items)
    return subtotal * (1 + tax_rate)


# Bad — inconsistent spacing, no blank lines
def calculate_total(items,tax_rate=0.08):
    subtotal=sum(item.price for item in items)
    return subtotal*(1+tax_rate)
  

Naming Conventions

Type Convention Example
Variables, functions snake_case user_name, get_total()
Classes PascalCase UserAccount, HTTPClient
Constants UPPER_SNAKE MAX_RETRIES, API_URL
Private (convention) _leading_underscore _internal_cache
Module names lowercase utils.py, models.py

Imports

  # Standard library first, then third-party, then local
import os
import sys

import requests
from django.db import models

from myapp.utils import helper
  

Avoid from module import * — it pollutes the namespace.

Docstrings

Document every public module, class, and function:

  def calculate_discount(price: float, percent: float) -> float:
    """Apply a percentage discount to a price.

    Args:
        price: Original price (must be non-negative).
        percent: Discount percentage (0–100).

    Returns:
        The discounted price.

    Raises:
        ValueError: If price or percent is negative.
    """
    if price < 0 or percent < 0:
        raise ValueError("Price and percent must be non-negative")
    return price * (1 - percent / 100)
  

Access docstrings at runtime:

  help(calculate_discount)
print(calculate_discount.__doc__)
  

Class Docstrings

  class BankAccount:
    """A simple bank account with deposit and withdraw operations.

    Attributes:
        owner: Name of the account holder.
        balance: Current account balance.
    """

    def __init__(self, owner: str, balance: float = 0.0):
        self.owner = owner
        self.balance = balance
  

Comments — When and When Not

  # Good — explains WHY
# Retry because the API occasionally returns 503 during deploys
response = retry_request(url, max_attempts=3)

# Bad — explains WHAT (the code already shows this)
# Increment counter by 1
counter += 1
  

Write self-documenting code with clear names. Use comments for non-obvious business logic or workarounds.

Formatting Tools

Automate style with these tools:

  pip install black isort flake8

black my_script.py       # auto-format
isort my_script.py       # sort imports
flake8 my_script.py      # lint for style/errors
  

Configure in pyproject.toml:

  [tool.black]
line-length = 88

[tool.isort]
profile = "black"
  

The Zen of Python

  import this
  

Key principles:

  • Beautiful is better than ugly
  • Explicit is better than implicit
  • Simple is better than complex
  • Readability counts

Consistent style makes collaboration easier and reduces bugs. Next: Control Flow.