Zen of Python
invalidemail at aerojockey.com
Wed Jan 19 19:52:13 EST 2005
Timothy Fitz wrote:
> While I agree that the Zen of Python is an amazingly concise list of
> truisms, I do not see any meaning in:
> Flat is better than nested.
> I strive for balance between flat and nested. Does anyone have a good
> example of where this is applied? (specifically to python, or in
I think the essence of why this Zen is true is the recognition that the
world isn't really organized into a nice, proper, perfect heirarchy,
where every node is a perfect little subset of its parent.
The fact is, some things are flat. A list is flat. Is is not better
to deal with flat things flatly?
And some things aren't flat, but they're not nested either. Rather,
they are various overlapping sets, but not subsets. It it better to
deal with such as mess by shoehorning it into a heirarchy that isn't
applicable, or to make it flat and deal with the subsets individually?
I shall give two examples of where Python exhibits this Zen, and doing
one my favorite things in the process: slamming other languages.
There are two ways to iterate: the flat way, with a for loop or list
comprehension or something like that; and the nested way, recursively.
We all know that recursion is often absolutely necessary. But usually
flat iteration suffices.
In other languages (notoriously LISP and functional languages), there
is a tendency to do it recursively anyways. For example, the following
Python code illustrates a recursive way to copy a list that would be
considered an example of "good code" in a language such as LISP:
. def copylist(a):
. if a: return a[:1] + copylist(a[1:])
. else: return a
LISP, of course, was designed to make recursive processing like this
easy and efficient. But it doesn't, IMHO, keep recursion from being
much harder to figure out. Although this has a sort of coolness in
that you can see the list copy operation reduced to its simplest
possible form (in the same way that Game of Life is cool because you
get all kinds of complexity from very simple rules), it completely
misses the big picture. When I want to copy a list, I want to copy a
list; I don't want to figure out the minimal rule set I could use to do
it. Iteration fits the mind better.
Python, IMO, wisely put the focus on iteration.
In many languages, the only way to get dynamic polymorphism is to
subclass. If two classes are to share an interface, they have to both
be subclasses of a common base class. If you have lots of classes that
you want to share parts of their interfaces, you have to put them all
into that heirarchy.
The problem is, the world isn't a neatly organized tree, where every
type of object must have functionality that is an exact proper subset
of some other type of object. So what you end up with is this big,
messy, inflexible hierarchy of classes that is difficult to make
changes or add new options to. Many classes have stuff in them that
ought not to be there, just to satisfy the requirements of subclassing.
Oftentimes, the root class has lots of methods that many subclasses
don't implement. Oftentimes, there will be subclasses with
functionality that isn't polymorphic because the root class doesn't
define virtual methods for them.
(For an example of all this madness: in I/O hierarchies, the base class
often has seek() and tell() methods, but since not all streams are
seekable, it also has to have a seekable() method. Thus, polymorphic
behavior and its benefits are abandoned in favor of the procedural way.
Sure, for this case, you could just define a SeekableStream
intermediate class, only for seekable streams. But here's the thing:
there are any number of functionalities a stream may or may not have.
Are you going to design a hierarchy with branches to account for all
possible combinations of them?)
Not so in Python. In Python, if you want to classes to have the same
interface, then write two classes that have the same methods. Bam, you
got polymorphism. No shoehorning into a heirarchy necessary. It's
what we call duck typing. (If it looks like a duck, and floats like a
duck, it's made of wood.)
The flat method of polymorphism is so much better it isn't even funny.
Again, Python chose wisely.
More information about the Python-list