Advanced

Best Practices

Write clean, maintainable Python code following PEP 8, proper naming, debugging techniques, and testing fundamentals.

PEP 8 Style Guide

PEP 8 is the official Python style guide. Following it makes your code consistent and readable:

  • Use 4 spaces for indentation (never tabs).
  • Limit lines to 79 characters (72 for docstrings).
  • Use blank lines: 2 between top-level definitions, 1 between methods.
  • Put imports at the top of the file, one per line.
  • Use spaces around operators: x = 1, not x=1.

Naming Conventions

TypeConventionExample
Variables / Functionssnake_caseuser_name, get_data()
ClassesPascalCaseMyClass, DataProcessor
ConstantsUPPER_SNAKE_CASEMAX_SIZE, API_KEY
PrivateLeading underscore_internal_method
Modulessnake_casemy_module.py

Code Organization

Project Structure
my_project/
├── my_project/
│   ├── __init__.py
│   ├── core.py
│   ├── utils.py
│   └── models.py
├── tests/
│   ├── __init__.py
│   ├── test_core.py
│   └── test_utils.py
├── requirements.txt
├── setup.py
├── README.md
└── .gitignore

Virtual Environments & Requirements

Terminal
# Create and activate venv
python3 -m venv venv
source venv/bin/activate

# Install dependencies
pip install requests pandas flask

# Save requirements
pip freeze > requirements.txt

# Reproduce environment elsewhere
pip install -r requirements.txt

Debugging

Python
# Print debugging (quick and dirty)
print(f"DEBUG: x = {x}, type = {type(x)}")

# Python debugger (pdb)
import pdb; pdb.set_trace()  # Drops into interactive debugger

# Breakpoint (Python 3.7+)
breakpoint()  # Same as pdb.set_trace()

# Common pdb commands:
# n (next line), s (step into), c (continue),
# p variable (print), l (list code), q (quit)

Testing

test_math.py (unittest)
import unittest

def add(a, b):
    return a + b

class TestAdd(unittest.TestCase):
    def test_positive(self):
        self.assertEqual(add(2, 3), 5)

    def test_negative(self):
        self.assertEqual(add(-1, -1), -2)

    def test_zero(self):
        self.assertEqual(add(0, 0), 0)

if __name__ == "__main__":
    unittest.main()
test_math_pytest.py (pytest)
# pytest is simpler - just use assert
def test_add_positive():
    assert add(2, 3) == 5

def test_add_negative():
    assert add(-1, -1) == -2

# Run with: pytest test_math_pytest.py -v

Common Mistakes

  • Mutable default arguments: def f(items=[]) shares the list across calls.
  • Modifying a list while iterating: Use a copy or list comprehension instead.
  • Using == for None: Always use is None or is not None.
  • Bare except: Always catch specific exceptions, not except:.
  • Circular imports: Restructure code to avoid modules importing each other.
  • Not closing files: Always use with statement for file operations.

Frequently Asked Questions

Always learn Python 3. Python 2 reached end-of-life on January 1, 2020, and no longer receives security updates. All modern libraries and frameworks target Python 3.

Use a list when you need a mutable collection that may change size. Use a tuple for fixed collections that should not change, like coordinates, RGB values, or function return values.

VS Code with the Python extension is the most popular choice. PyCharm is more feature-rich out of the box. For data science, Jupyter Notebook or JupyterLab is preferred.

Not necessarily for simple scripts and data analysis. However, understanding OOP is valuable for larger projects, working with frameworks (Django, Flask), and most job requirements.

Use specific exception types, log errors properly (use the logging module instead of print), implement retry logic for transient failures, and never silence exceptions with bare except: pass.