🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
Search courses…
💼 Servicesℹ️ About✉️ ContactView Pricing Plansfrom $10

Python Best Practices — Writing Clean Code

Python QualityBest Practices🟢 Free Lesson

Advertisement

Python Best Practices — Writing Clean Code

Writing clean, maintainable code is a skill that separates junior from senior developers. Follow these practices to write professional Python code.

Learning Objectives

  • Follow PEP 8 style guidelines consistently
  • Write Pythonic idioms that leverage language features
  • Structure projects for maintainability and scalability
  • Handle errors gracefully with proper exception hierarchy

PEP 8 Style Guide

The foundation of Python code style:

# Naming conventions
class UserManager:          # CamelCase for classes
    MAX_RETRIES = 3         # UPPER_CASE for constants

    def get_user(self):     # snake_case for functions/methods
        user_name = ""      # snake_case for variables

# Line length: 79 characters max (72 for docstrings)
# Imports: one per line, grouped (stdlib, third-party, local)
import os
import sys
from pathlib import Path

from flask import Flask
from sqlalchemy import Column

from myapp.models import User

# Whitespace matters
x = 1
y = x + 1
d = {"key": "value"}
lst = [1, 2, 3]

Pythonic Idioms

Write idiomatic Python that leverages the language:

# Use enumerate instead of manual index
for i, item in enumerate(items):
    print(i, item)

# Use zip for parallel iteration
for name, score in zip(names, scores):
    print(f"{name}: {score}")

# Use any/all for boolean checks
if any(x > 10 for x in numbers):
    print("Found large number")

# Use context managers (always!)
with open("file.txt") as f:
    data = f.read()

# Use f-strings (Python 3.6+)
message = f"Hello, {name}!"

# EAFP — Easier to Ask Forgiveness than Permission
try:
    value = my_dict["key"]
except KeyError:
    value = default

# Use unpacking
first, *middle, last = [1, 2, 3, 4, 5]
# first=1, middle=[2,3,4], last=5

SOLID Principles

Apply these object-oriented design principles:

PrincipleMeaningExample
Single ResponsibilityOne class = one jobUser class handles users, not email sending
Open/ClosedOpen for extension, closed for modificationUse abstract base classes
Liskov SubstitutionSubtypes must be substitutableDog subclass works where Animal expected
Interface SegregationSmall, specific interfacesSeparate Readable and Writable
Dependency InversionDepend on abstractionsUse ABC, not concrete classes

Project Structure

Organize code for maintainability:

Architecture Diagram
my_project/
+-- src/
|   +-- my_package/
|       +-- __init__.py
|       +-- models/
|       |   +-- __init__.py
|       |   +-- user.py
|       +-- services/
|       |   +-- __init__.py
|       |   +-- auth.py
|       +-- utils/
|           +-- __init__.py
|           +-- helpers.py
+-- tests/
|   +-- __init__.py
|   +-- test_models/
|   +-- test_services/
+-- pyproject.toml
+-- README.md
+-- .gitignore

Error Handling Best Practices

Be specific and informative:

# Be specific with exceptions
try:
    result = risky_operation()
except ValueError as e:
    logger.error(f"Value error: {e}")
    raise
except ConnectionError:
    logger.error("Connection failed")
    return fallback_value

# Create custom exceptions for your domain
class InsufficientFundsError(Exception):
    def __init__(self, balance, amount):
        self.balance = balance
        self.amount = amount
        super().__init__(
            f"Insufficient funds: balance={balance}, requested={amount}"
        )

# Don't catch all exceptions — be specific
# BAD: except Exception:
# GOOD: except (ValueError, TypeError) as e:

Documentation Standards

Write clear, useful documentation:

def calculate_discount(price: float, discount: float) -> float:
    """Calculate discounted price.

    Args:
        price: Original price (must be positive)
        discount: Discount percentage (0.0 to 1.0)

    Returns:
        Price after discount

    Raises:
        ValueError: If discount is not between 0 and 1

    Example:
        >>> calculate_discount(100.0, 0.2)
        80.0
    """
    if not 0 <= discount <= 1:
        raise ValueError(f"Discount must be 0-1, got {discount}")
    return price * (1 - discount)

Code Review Checklist

Before submitting code, verify:

  • Functions do one thing (Single Responsibility)
  • Names are descriptive (no x, tmp, data)
  • No duplicated code (DRY principle)
  • Error handling is specific (not bare except:)
  • Public functions have docstrings
  • Tests cover edge cases
  • No hardcoded values (use constants or config)
  • Imports are organized (stdlib -> third-party -> local)

Common Mistakes

MistakeProblemBetter Approach
Mutable default argsdef f(x=[])def f(x=None) then x = x or []
Bare exceptCatches everythingCatch specific exceptions
Global stateHard to test and debugPass dependencies explicitly
Over-abstractionUnnecessary complexityKeep it simple (YAGNI)
Premature optimizationOptimize before profilingProfile first, optimize second

Key Takeaways

  1. Follow PEP 8 for consistent style — use black formatter to automate
  2. Use Pythonic idioms: enumerate, zip, context managers, f-strings, EAFP
  3. Be specific with exception handling — never use bare except:
  4. Write docstrings for all public functions — Google or NumPy style
  5. Keep functions small and focused — one function = one job
  6. Use type hints to catch bugs early and improve IDE support

Premium Content

Python Best Practices — Writing Clean Code

Unlock this lesson and 900+ advanced tutorials with a Premium plan.

🎯End-to-end Projects
💼Interview Prep
📜Certificates
🤝Community Access

Already a member? Log in

Need Expert Python Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement