Skip to main content

Naming Style and Readability

What You'll Learn

Python's official naming conventions, how to write code that reads like prose, and when and how to document your code.

Why Readability Matters

"Code is read far more often than it is written." — Guido van Rossum

You will spend more time reading code (yours and others') than writing it. Readable code:

  • Is easier to debug
  • Is easier for teammates to understand
  • Is less likely to have hidden bugs
  • Is easier to modify safely

PEP 8 — Python's Style Guide

PEP 8 is the official Python style guide. Here are the most important rules:

Naming Conventions

WhatConventionExample
Variablessnake_caseuser_name, total_count
Functionssnake_caseget_user(), calculate_total()
ConstantsUPPER_SNAKE_CASEMAX_RETRIES, BASE_URL
ClassesPascalCaseUserAccount, DatabaseError
Private (internal)_leading_underscore_internal_helper
Modules/fileslowercase or snake_caseutils.py, db_client.py
# ✅ Good
MAX_CONNECTIONS = 10
user_email = "[email protected]"

def calculate_average(numbers):
...

class UserProfile:
...

# ❌ Bad
maxConn = 10 # camelCase for variable
UserEmail = "alice" # PascalCase for variable
CalculateAverage() # PascalCase for function
userprofile = ... # lowercase for class

Descriptive Names

# ❌ Cryptic
def calc(x, y, z):
return x * y + z

# ✅ Clear
def calculate_discounted_price(base_price, discount_rate, shipping_cost):
return base_price * (1 - discount_rate) + shipping_cost

Avoid single-letter names except for:

  • Loop counters: i, j, k
  • Math variables where it's conventional: x, y in geometry
  • Lambda one-liners: lambda x: x * 2

Whitespace and Spacing

# Around operators
x = 5 + 3 # ✅
x=5+3 # ❌

# After commas
print(a, b, c) # ✅
print(a,b,c) # ❌

# Around = in keyword arguments (no spaces)
print(end="") # ✅
print(end = "") # ❌

# Blank lines
# 2 blank lines between top-level definitions
def first_function():
...


def second_function():
...

# 1 blank line between methods inside a class
class MyClass:
def first(self):
...

def second(self):
...

Line Length

PEP 8 recommends 79 characters per line (many teams allow 99 or 120).

Break long lines using parentheses:

# Long function call — break inside parentheses
result = some_function(
argument_one,
argument_two,
argument_three,
)

# Long condition
if (
user.is_active
and user.has_permission("write")
and not user.is_banned
):
proceed()

# Long string
message = (
"This is a very long message that "
"spans multiple lines for readability."
)

Comments

Good comments explain why, not what (the code shows what):

# ❌ Useless comment (restates the code)
x = x + 1 # increment x by 1

# ✅ Useful comment (explains the reason)
x = x + 1 # offset by 1 because array is 0-indexed but display is 1-indexed

# ❌ Wrong comment (misleading!)
y = x * 2 # double the price (actually doubles the count!)

# ✅ Correct and useful
item_count = raw_count * 2 # multiply by 2: each container holds 2 items

Block comments (above the code they describe):

# Retry up to 3 times with exponential backoff.
# The API has a rate limit of 100 requests/minute.
for attempt in range(3):
...

Inline comments (same line, at least 2 spaces):

timeout = 30 # seconds; API SLA requires response within 25s

Docstrings

Docstrings document what a function does, its parameters, and return value:

def calculate_bmi(weight_kg: float, height_m: float) -> float:
"""
Calculate Body Mass Index (BMI).

Args:
weight_kg: Weight in kilograms.
height_m: Height in metres.

Returns:
BMI value as a float.

Raises:
ValueError: If height_m is zero or negative.
"""
if height_m <= 0:
raise ValueError(f"height_m must be positive, got {height_m}")
return weight_kg / (height_m ** 2)

Access docstrings with help():

help(calculate_bmi)

Type Hints

Type hints make code self-documenting:

# Without type hints
def greet(name):
return "Hello, " + name

# With type hints — clearer what goes in and comes out
def greet(name: str) -> str:
return "Hello, " + name

# More complex types
from typing import Optional

def find_user(user_id: int) -> Optional[str]:
"""Returns username or None if not found."""
...

Auto-Formatting Tools

Don't spend time manually formatting — use tools:

# black: opinionated auto-formatter
pip install black
black src/

# ruff: fast linter + formatter
pip install ruff
ruff check src/
ruff format src/

# isort: sorts import statements
pip install isort
isort src/

Quick Reference

# Naming
variable_name = ... # snake_case
CONSTANT_NAME = ... # UPPER_SNAKE_CASE
def function_name(): ... # snake_case
class ClassName: ... # PascalCase

# Spacing
x = a + b # spaces around operators
func(a, b, c) # spaces after commas
func(key="value") # no spaces around = in kwargs

# Comments
# Explain why, not what

# Docstring
def fn(x: int) -> str:
"""Short description.

Args:
x: What x is.

Returns:
What the function returns.
"""

# Type hints
def fn(name: str, count: int = 1) -> list[str]:
...

What's Next

Module 3: Data Structures