Chapter 1. (Avoiding) Flow Control
In typical imperative Python programs—including those that make use of
classes and methods to hold their imperative code—a block of code
generally consists of some outside loops (for or while), assignment
of state variables within those loops, modification of data structures
like dicts, lists, and sets (or various other structures, either from
the standard library or from third-party packages), and some branch
statements (if/elif/else or try/except/finally). All of
this is both natural and seems at first easy to reason about. The
problems often arise, however, precisely with those side effects that
come with state variables and mutable data structures; they often model
our concepts from the physical world of containers fairly well, but it
is also difficult to reason accurately about what state data is in at a
given point in a program.
One solution is to focus not on constructing a data collection but rather on describing “what” that data collection consists of. When one simply thinks, “Here’s some data, what do I need to do with it?” rather than the mechanism of constructing the data, more direct reasoning is often possible. The imperative flow control described in the last paragraph is much more about the “how” than the “what” and we can often shift the question.
Encapsulation
One obvious way of focusing more on “what” than “how” is simply to refactor code, and to put the data construction in a more isolated place—i.e., in a function or method. ...