Item 22: Prefer Helper Classes Over Bookkeeping with Dictionaries and Tuples
Avoid making dictionaries with values that are other dictionaries or long tuples;
Use namedtuple for lightweight, immutable data containers before you need the flexibility of a full class;
Move your bookkeeping code to use multiple helper classes when your internal state dictionaries get complicated;
Avoid making dictionaries with values that are other dictionaries or long tuples;
Item 23: Accept Functions for Simple Interfaces Instead of Classes
Instead of defining and instantiating classes, functions are often all you need for simple interfaces between components in Python;
References to functions and methods in Python are first class, meaning they can be used in expressions like any other type;
The __call__ special method enables instances of a class to be called like plain Python functions;
When you need a function to maintain state, consider defining a class that provides the __call__ method instead of defining a stateful closure.
Item 24: Use @classmethod Polymorphism to Construct Objects Generically
Python only supports a single constructor per class, the __init__ method;
Use @classmethod to define alternative constructors for your classes;
Use class method polymorphism to provide generic ways to build and connect concrete subclasses.
Item 25: Initialize Parent Classes with super
Python’s standard method resolution order (MRO) solves the problems of superclass initialization order and diamond inheritance;
Always use the super built-in function to initialize parent classes.
Item 26: Use Multiple Inheritance Only for Mix-in Utility Classes
Avoid using multiple inheritance if mix-in classes can achieve the same outcome;
Use pluggable behaviors at the instance level to provide per-class customization when mix-in classes may require it;
Compose mix-ins to create complex functionality from simple behaviors.
Item 27: Prefer Public Attributes Over Private Ones
Private attributes aren’t rigorously enforced by the Python compiler;
Plan from the beginning to allow subclasses to do more with your internal APIs and attributes instead of locking them out by default;
Use documentation of protected fields to guide subclasses instead of trying to force access control with private attributes;
Only consider using private attributes to avoid naming conflicts with subclasses that are out of your control.
Item 28: Inherit from collections.abc for Custom Container Types
Inherit directly from Python’s container types (like list or dict) for simple use cases;
Beware of the large number of methods required to implement custom container types correctly;
Have your custom container types inherit from the interfaces defined in collections.abc to ensure that your classes match required interfaces and behaviors.