Python Notes
Master Python best practices and coding standards — PEP 8 style guide, clean code principles, naming conventions, documentation, type hints, logging, testing, virtual environments, and professional Python patterns.
Writing Python code that works is one thing — writing Python code that is readable, maintainable, and professional is another. This guide covers the practices used by experienced Python developers.
PEP 8 — The Python Style Guide
PEP 8 is the official style guide for Python code. Most Python projects follow it.
Indentation and Spacing
# ✅ Correct — 4 spaces per indent level
def calculate_area(length, width):
area = length * width
return area
# ❌ Wrong — 2 spaces or tabs
def calculate_area(length, width):
area = length * width
return area
# ✅ Blank lines: 2 between top-level, 1 between methods
class MyClass:
def method_one(self):
pass
def method_two(self):
pass
def standalone_function():
pass
another_function = lambda x: x * 2Naming Conventions
# Variables and functions — snake_case
user_name = "Alice"
total_price = 99.99
max_retries = 3
def get_user_by_id(user_id):
return user_id
def calculate_monthly_payment(principal, rate, term):
return principal * rate / (1 - (1 + rate) ** -term)
# Classes — PascalCase
class UserAccount:
pass
class DatabaseConnection:
pass
class HTTPRequestHandler:
pass
# Constants — SCREAMING_SNAKE_CASE
MAX_CONNECTIONS = 100
API_BASE_URL = "https://api.example.com"
DEFAULT_TIMEOUT = 30
PI = 3.14159265
# Private (internal) — leading underscore
class MyClass:
def __init__(self):
self._internal_value = 42 # Convention: internal use
self.__name_mangled = "test" # Name mangling (avoid external access)
def _helper_method(self):
pass # Internal helper
# Modules — short, all lowercase
import os
import sys
import json
# Not: import MyModule, import MyModule_Utils
# Packages — lowercase, short, no hyphens
# mypackage/utils.py ✅
# MyPackage/Utils.py ❌Line Length and Wrapping
# Max 79 characters (88 with Black formatter)
# PEP 8 recommends 79, Black uses 88
# ✅ Long function calls — use parentheses for implicit continuation
result = some_function(
argument_one,
argument_two,
argument_three,
keyword_arg=some_value,
)
# ✅ Long imports
from mypackage.module import (
ClassOne,
ClassTwo,
function_one,
function_two,
)
# ✅ Long conditions
if (condition_one
and condition_two
and condition_three):
do_something()
# ✅ Long strings
message = (
"This is a very long message that "
"needs to be split across multiple "
"lines for readability."
)Type Hints
Type hints make your code self-documenting and catch bugs early:
Docstrings
Document your code properly:
def calculate_compound_interest(
principal: float,
rate: float,
time: int,
n: int = 12
) -> float:
"""
Calculate compound interest.
The formula used is: A = P(1 + r/n)^(nt)
Args:
principal: Initial investment amount in dollars.
rate: Annual interest rate as a decimal (e.g., 0.05 for 5%).
time: Number of years.
n: Number of times interest compounds per year. Default is 12 (monthly).
Returns:
Final amount after compound interest.
Raises:
ValueError: If principal, rate, or time are negative.
Examples:
>>> calculate_compound_interest(1000, 0.05, 10)
1647.009...
>>> calculate_compound_interest(5000, 0.08, 20, 4) # Quarterly
24647.38...
"""
if principal < 0 or rate < 0 or time < 0:
raise ValueError("Principal, rate, and time must be non-negative")
return principal * (1 + rate / n) ** (n * time)
class DatabaseManager:
"""
Manage database connections and operations.
This class provides a high-level interface for database operations,
handling connection pooling, transactions, and error recovery.
Attributes:
host: Database server hostname.
port: Database server port.
database: Database name.
pool_size: Maximum number of pooled connections.
Example:
>>> db = DatabaseManager("localhost", 5432, "mydb")
>>> with db.connect() as conn:
... result = conn.execute("SELECT * FROM users")
"""
def __init__(self, host: str, port: int, database: str, pool_size: int = 5):
"""
Initialize the DatabaseManager.
Args:
host: Database server hostname.
port: Database server port.
database: Database name.
pool_size: Max connections in pool.
"""
self.host = host
self.port = port
self.database = database
self.pool_size = pool_sizeClean Code Principles
Single Responsibility
DRY — Don't Repeat Yourself
# ❌ Repeated code
def validate_name(name):
if not name:
raise ValueError("Name cannot be empty")
if len(name) < 2:
raise ValueError("Name must be at least 2 characters")
if len(name) > 100:
raise ValueError("Name must be at most 100 characters")
return name.strip()
def validate_city(city):
if not city:
raise ValueError("City cannot be empty")
if len(city) < 2:
raise ValueError("City must be at least 2 characters")
if len(city) > 100:
raise ValueError("City must be at most 100 characters")
return city.strip()
# ✅ DRY — reusable validation
def validate_string_field(value: str, field_name: str, min_len=2, max_len=100) -> str:
"""Validate a string field with standard rules."""
if not value:
raise ValueError(f"{field_name} cannot be empty")
stripped = value.strip()
if len(stripped) < min_len:
raise ValueError(f"{field_name} must be at least {min_len} characters")
if len(stripped) > max_len:
raise ValueError(f"{field_name} must be at most {max_len} characters")
return stripped
validate_name = lambda n: validate_string_field(n, "Name")
validate_city = lambda c: validate_string_field(c, "City")
validate_bio = lambda b: validate_string_field(b, "Bio", min_len=10, max_len=500)Logging
Use logging instead of print statements:
Virtual Environments
# Create virtual environment
python -m venv venv
# Activate
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Create requirements.txt
pip freeze > requirements.txt
# Install exact versions (reproducible)
pip install -r requirements.txt
# Using pip-tools (better dependency management)
pip install pip-tools
# requirements.in — direct dependencies (no versions)
# requirements.txt — pinned transitive deps (generated)
pip-compile requirements.in
# Using pyenv (manage multiple Python versions)
# brew install pyenv (macOS)
# pyenv install 3.12.3
# pyenv local 3.12.3Code Formatting Tools
Project Structure
Summary
Key best practices covered:
- ✅ PEP 8 formatting (indentation, naming, line length)
- ✅ Type hints for self-documenting code
- ✅ Docstrings (Google/NumPy/Sphinx style)
- ✅ Single Responsibility Principle
- ✅ DRY — eliminating code duplication
- ✅ Proper logging (not print statements)
- ✅ Virtual environments for isolation
- ✅ Code formatting tools (Black, isort, flake8, mypy)
- ✅ Professional project structure
*Next: Common Errors →*
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Python Best Practices.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Python Master Course topic.
Search Terms
python-master-course, python master course, python, master, course, resources, best, practices
Related Python Master Course Topics