Contents

  1. Preface

  2. Acknowledgments

  3. About the Author

  4. Chapter 1 Pythonic Thinking

    1. Item 1: Know Which Version of Python You’re Using

    2. Item 2: Follow the PEP 8 Style Guide

    3. Item 3: Never Expect Python to Detect Errors at Compile Time

    4. Item 4: Write Helper Functions Instead of Complex Expressions

    5. Item 5: Prefer Multiple-Assignment Unpacking over Indexing

    6. Item 6: Always Surround Single-Element Tuples with Parentheses

    7. Item 7: Consider Conditional Expressions for Simple Inline Logic

    8. Item 8: Prevent Repetition with Assignment Expressions

    9. Item 9: Consider match for Destructuring in Flow Control; Avoid When if Statements Are Sufficient

  5. Chapter 2 Strings and Slicing

    1. Item 10: Know the Differences Between bytes and str

    2. Item 11: Prefer Interpolated F-Strings over C-Style Format Strings and str.format

    3. Item 12: Understand the Difference Between repr and str when Printing Objects

    4. Item 13: Prefer Explicit String Concatenation over Implicit, Especially in Lists

    5. Item 14: Know How to Slice Sequences

    6. Item 15: Avoid Striding and Slicing in a Single Expression

    7. Item 16: Prefer Catch-All Unpacking over Slicing

  6. Chapter 3 Loops and Iterators

    1. Item 17: Prefer enumerate over range

    2. Item 18: Use zip to Process Iterators in Parallel

    3. Item 19: Avoid else Blocks After for and while Loops

    4. Item 20: Never Use for Loop Variables After the Loop Ends

    5. Item 21: Be Defensive when Iterating over Arguments

    6. Item 22: Never Modify Containers While Iterating over Them; Use Copies or Caches Instead

    7. Item 23: Pass Iterators to any and all for Efficient Short-Circuiting Logic

    8. Item 24: Consider itertools for Working with Iterators and Generators

  7. Chapter 4 Dictionaries

    1. Item 25: Be Cautious when Relying on Dictionary Insertion Ordering

    2. Item 26: Prefer get over in and KeyError to Handle Missing Dictionary Keys

    3. Item 27: Prefer defaultdict over setdefault to Handle Missing Items in Internal State

    4. Item 28: Know How to Construct Key-Dependent Default Values with __missing__

    5. Item 29: Compose Classes Instead of Deeply Nesting Dictionaries, Lists, and Tuples

  8. Chapter 5 Functions

    1. Item 30: Know That Function Arguments Can Be Mutated

    2. Item 31: Return Dedicated Result Objects Instead of Requiring Function Callers to Unpack More Than Three Variables

    3. Item 32: Prefer Raising Exceptions to Returning None

    4. Item 33: Know How Closures Interact with Variable Scope and nonlocal

    5. Item 34: Reduce Visual Noise with Variable Positional Arguments

    6. Item 35: Provide Optional Behavior with Keyword Arguments

    7. Item 36: Use None and Docstrings to Specify Dynamic Default Arguments

    8. Item 37: Enforce Clarity with Keyword-Only and Positional-Only Arguments

    9. Item 38: Define Function Decorators with functools.wraps

    10. Item 39: Prefer functools.partial over lambda Expressions for Glue Functions

  9. Chapter 6 Comprehensions and Generators

    1. Item 40: Use Comprehensions Instead of map and filter

    2. Item 41: Avoid More Than Two Control Subexpressions in Comprehensions

    3. Item 42: Reduce Repetition in Comprehensions with Assignment Expressions

    4. Item 43: Consider Generators Instead of Returning Lists

    5. Item 44: Consider Generator Expressions for Large List Comprehensions

    6. Item 45: Compose Multiple Generators with yield from

    7. Item 46: Pass Iterators into Generators as Arguments Instead of Calling the send Method

    8. Item 47: Manage Iterative State Transitions with a Class Instead of the Generator throw Method

  10. Chapter 7 Classes and Interfaces

    1. Item 48: Accept Functions Instead of Classes for Simple Interfaces

    2. Item 49: Prefer Object-Oriented Polymorphism over Functions with isinstance Checks

    3. Item 50: Consider functools.singledispatch for Functional-Style Programming Instead of Object-Oriented Polymorphism

    4. Item 51: Prefer dataclasses for Defining Lightweight Classes

    5. Item 52: Use @classmethod Polymorphism to Construct Objects Generically

    6. Item 53: Initialize Parent Classes with super

    7. Item 54: Consider Composing Functionality with Mix-in Classes

    8. Item 55: Prefer Public Attributes over Private Ones

    9. Item 56: Prefer dataclasses for Creating Immutable Objects

    10. Item 57: Inherit from collections.abc Classes for Custom Container Types

  11. Chapter 8 Metaclasses and Attributes

    1. Item 58: Use Plain Attributes Instead of Setter and Getter Methods

    2. Item 59: Consider @property Instead of Refactoring Attributes

    3. Item 60: Use Descriptors for Reusable @property Methods

    4. Item 61: Use __getattr__, __getattribute__, and __setattr__ for Lazy Attributes

    5. Item 62: Validate Subclasses with __init_subclass__

    6. Item 63: Register Class Existence with __init_subclass__

    7. Item 64: Annotate Class Attributes with __set_name__

    8. Item 65: Consider Class Body Definition Order to Establish Relationships Between Attributes

    9. Item 66: Prefer Class Decorators over Metaclasses for Composable Class Extensions

  12. Chapter 9 Concurrency and Parallelism

    1. Item 67: Use subprocess to Manage Child Processes

    2. Item 68: Use Threads for Blocking I/O; Avoid for Parallelism

    3. Item 69: Use Lock to Prevent Data Races in Threads

    4. Item 70: Use Queue to Coordinate Work Between Threads

    5. Item 71: Know How to Recognize When Concurrency Is Necessary

    6. Item 72: Avoid Creating New Thread Instances for On-Demand Fan-out

    7. Item 73: Understand How Using Queue for Concurrency Requires Refactoring

    8. Item 74: Consider ThreadPoolExecutor When Threads Are Necessary for Concurrency

    9. Item 75: Achieve Highly Concurrent I/O with Coroutines

    10. Item 76: Know How to Port Threaded I/O to asyncio

    11. Item 77: Mix Threads and Coroutines to Ease the Transition to asyncio

    12. Item 78: Maximize Responsiveness of asyncio Event Loops with async-Friendly Worker Threads

    13. Item 79: Consider concurrent.futures for True Parallelism

  13. Chapter 10 Robustness

    1. Item 80: Take Advantage of Each Block in try/except/else/finally

    2. Item 81: assert Internal Assumptions and raise Missed Expectations

    3. Item 82: Consider contextlib and with Statements for Reusable try/finally Behavior

    4. Item 83: Always Make try Blocks as Short as Possible

    5. Item 84: Beware of Exception Variables Disappearing

    6. Item 85: Beware of Catching the Exception Class

    7. Item 86: Understand the Difference Between Exception and BaseException

    8. Item 87: Use traceback for Enhanced Exception Reporting

    9. Item 88: Consider Explicitly Chaining Exceptions to Clarify Tracebacks

    10. Item 89: Always Pass Resources into Generators and Have Callers Clean Them Up Outside

    11. Item 90: Never Set __debug__ to False

    12. Item 91: Avoid exec and eval Unless You’re Building a Developer Tool

  14. Chapter 11 Performance

    1. Item 92: Profile Before Optimizing

    2. Item 93: Optimize Performance-Critical Code Using timeit Microbenchmarks

    3. Item 94: Know When and How to Replace Python with Another Programming Language

    4. Item 95: Consider ctypes to Rapidly Integrate with Native Libraries

    5. Item 96: Consider Extension Modules to Maximize Performance and Ergonomics

    6. Item 97: Rely on Precompiled Bytecode and File System Caching to Improve Startup Time

    7. Item 98: Lazy-Load Modules with Dynamic Imports to Reduce Startup Time

    8. Item 99: Consider memoryview and bytearray for Zero-Copy Interactions with bytes

  15. Chapter 12 Data Structures and Algorithms

    1. Item 100: Sort by Complex Criteria Using the key Parameter

    2. Item 101: Know the Difference Between sort and sorted

    3. Item 102: Consider Searching Sorted Sequences with bisect

    4. Item 103: Prefer deque for Producer–Consumer Queues

    5. Item 104: Know How to Use heapq for Priority Queues

    6. Item 105: Use datetime Instead of time for Local Clocks

    7. Item 106: Use decimal when Precision Is Paramount

    8. Item 107: Make pickle Serialization Maintainable with copyreg

  16. Chapter 13 Testing and Debugging

    1. Item 108: Verify Related Behaviors in TestCase Subclasses

    2. Item 109: Prefer Integration Tests over Unit Tests

    3. Item 110: Isolate Tests from Each Other with setUp, tearDown, setUpModule, and tearDownModule

    4. Item 111: Use Mocks to Test Code with Complex Dependencies

    5. Item 112: Encapsulate Dependencies to Facilitate Mocking and Testing

    6. Item 113: Use assertAlmostEqual to Control Precision in Floating Point Tests

    7. Item 114: Consider Interactive Debugging with pdb

    8. Item 115: Use tracemalloc to Understand Memory Usage and Leaks

  17. Chapter 14 Collaboration

    1. Item 116: Know Where to Find Community-Built Modules

    2. Item 117: Use Virtual Environments for Isolated and Reproducible Dependencies

    3. Item 118: Write Docstrings for Every Function, Class, and Module

    4. Item 119: Use Packages to Organize Modules and Provide Stable APIs

    5. Item 120: Consider Module-Scoped Code to Configure Deployment Environments

    6. Item 121: Define a Root Exception to Insulate Callers from APIs

    7. Item 122: Know How to Break Circular Dependencies

    8. Item 123: Consider warnings to Refactor and Migrate Usage

    9. Item 124: Consider Static Analysis via typing to Obviate Bugs

    10. Item 125: Prefer Open Source Projects for Bundling Python Programs over zipimport and zipapp

  18. Index