1 Doing More with Python
2 Scaling With Generators
2.1 Iteration in Python
2.2 Generator Functions
2.3 Generator Patterns and Scalable Composability
2.4 Python is Filled With Iterators
2.5 The Iterator Protocol
3 Creating Collections with Comprehensions
3.1 List Comprehensions
3.2 Formatting For Readability (And More)
3.3 Multiple Sources and Filters
3.4 Comprehensions and Generators
3.5 Dictionaries, Sets, and Tuples
3.6 Limits of Comprehensions
4 Advanced Functions
4.1 Accepting & Passing Variable Arguments
4.2 Functions As Objects
4.3 Key Functions in Python
5 Decorators
5.1 The Basic Decorator
5.2 Data In Decorators
5.3 Decorators That Take Arguments
5.4 Class-based Decorators
5.5 Decorators For Classes
5.6 Preserving the Wrapped Function
6 Exceptions and Errors
6.1 The Basic Idea
6.2 Exceptions Are Objects
6.3 Raising Exceptions
6.4 Catching And Re-raising
6.5 The Most Diabolical Python Anti-Pattern
7 Classes and Objects: Beyond The Basics
7.1 Properties
7.2 The Factory Patterns
7.3 The Observer Pattern
7.4 Magic Methods
7.5 Rebelliously Misusing Magic Methods
8 Automated Testing and TDD
8.1 What is Test-Driven Development?
8.2 Unit Tests And Simple Assertions
8.3 Fixtures And Common Test Setup
8.4 Asserting Exceptions
8.5 Using Subtests
8.6 Final thoughts
9 Logging in Python
9.1 The Basic Interface
9.2 Configuring The Basic Interface
9.3 Passing Arguments
9.4 Beyond Basic: Loggers
9.5 Log Destinations: Handlers and Streams
9.6 Logging to Multiple Destinations
9.7 Record Layout with Formatters