Issue #35: Python,  Library

Tim Peters

Not everything that is worth reading is a book. A good programmer’s library (I will let you decide whether that is a good library owned by a programmer, or a library belonging to a good programmer) includes essays, scholarly articles, videos, magazines, blog posts, podcast episodes, and more. This month, we are going to read an Easter egg in a programming language.

Type import this into the Python interpreter and you will get a short collection of aphorisms that each summarise a design principle of the Python language (or really of Guido van Rossum). This document is published as PEP 20 — The Zen of Python.

This sort of information is priceless: knowing how your programming language was designed will help you understand how to read code written in it, and write your own code. There are only 19 lines, we may as well go through each one!

Beautiful is better than ugly.

Well, this is clearly subjective, but still important: we are taking subjective principles into account. We are considering not just the practicality of programming with this tool, but the experience of using the tool, too.

Explicit is better than implicit.

This can be read as a preference for configuration over convention: do things I say, and only things I say. In fact it is more likely to be a dig at a design choice in Perl, where unary functions (one argument) also have a nullary (zero-argument) form: chomp $foo; strips trailing whitespace from $foo, while chomp; acts on the $_ variable. Other operations implicitly set $_, so knowing the behaviour of a Perl script can mean knowing the behaviour of Perl, not understanding the instructions in the script.

Simple is better than complex.

Simple to implement, or simple to use? Yes.

Complex is better than complicated.

When something is not straightforward it should be because what you are trying to do is not straightforward; not because the tool makes it harder.

Flat is better than nested.

Think of the Law of Demeter: do not make people reach into the innards of modules or objects to find things that are useful. If they are useful, they belong at the surface.

Sparse is better than dense.

Various programming languages are great at “code golf”, providing incredibly terse ways to get a lot of functionality. Python is not. Python would prefer that you write out your program in a way that is easy to read.

Readability counts.

This seems to be coming up a lot! Python is a programming language that was not just designed for you, but for everyone you work with.

Special cases aren't special enough to break the rules.

The law of minimal surprise: both the common things and the edge cases should work in the same way, no matter how much you think it would be nicer to do it differently. Although…

Although practicality beats purity.

Indeed. If that uniformity gets in the way, abandon it.

Errors should never pass silently.

This is an important part of the user experience! If your program does not do what you think it does, you should find out quickly and loudly. This leads to design choices like KeyError for missing entries in a dictionary, which can be frustrating but ultimately lead to more robust code. Unless…

Unless explicitly silenced.

Of course, if you want to ignore an error, fill your boots.

In the face of ambiguity, refuse the temptation to guess.

Again, your program should do what you expect. If you have not told the computer enough information to understand what you expect, then you have not written your program yet.

There should be one-- and preferably only one --obvious way to do it.

This is broadly interpreted as a swing at Perl, which has the Tim Toady (TMTOWTDI—”there is more than one way to do it”) design maxim. And indeed it is. But it is also a broadside at all C flavoured languages. Look at the spacing around those hyphens: they are the prefix and postfix subtraction operators! Those definitely give us plenty more than one way to do subtraction. Resolving their effects, and eliding the parenthetical statement, we find a hidden twentieth aphorism, a little bonus piece of Python design knowledge:

There should be zero less-than-obvious ways to do it.

Although that way may not be obvious at first unless you're Dutch.

Guess where Guido van Rossum comes from.

Now is better than never.

Also known as “done is better than perfect”: get it out rather than getting paralysed by all these design choices.

Although never is often better than *right* now.

See Python 3000, which was still intentional vapourware at the time PEP-20 was written. If you know you are trying to fix core design problems, and you introduced those problems, you may still need to ruminate on the solution.

If the implementation is hard to explain, it's a bad idea.

If this thing is going to be easy to use, it needs to be easy to understand.

If the implementation is easy to explain, it may be a good idea.

Even if this thing is easy to understand, that understanding had better be correct!

Namespaces are one honking great idea -- let's do more of those!

While it is true that “flat is better than nested”, it is also true that qualified is better than global. My maths library and my data types library may well both have a set, and I should be allowed to call both of them “set”.

Cover photo by the author.

Donate using Liberapay

Graham is a senior Research Software Engineer at Oxford University. He got hooked on making quality software in front of a NeXT TurboStation Color, and still has a lot to learn.