Open a Python REPL and type:
>>> import this
You'll see:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
These 19 principles (20 if you count the missing one—more on that later) were written by Tim Peters in 1999. They're codified in PEP 20 and embedded in Python itself.
Beautiful is better than ugly
Code aesthetics matter. Python values clean, well-formatted code that's pleasant to read. This isn't superficial—readable code is maintainable code.
# Ugly
if(x==5):y=x+1
# Beautiful
if x == 5:
y = x + 1
PEP 8, Python's style guide, enforces this principle. Consistent spacing, naming conventions, and structure make code beautiful.
Explicit is better than implicit
Magic is tempting, but clarity wins. Don't hide behavior behind abstraction that makes the code hard to understand.
# Implicit
from math import *
result = sqrt(16) # Where did sqrt come from?
# Explicit
import math
result = math.sqrt(16) # Clear source
The wildcard import (*) pollutes the namespace. Explicit imports show dependencies.
Simple is better than complex
Prefer straightforward solutions. If two approaches solve the same problem, choose the simpler one.
# Complex
result = list(map(lambda x: x * 2, filter(lambda x: x > 0, numbers)))
# Simple
result = [x * 2 for x in numbers if x > 0]
List comprehensions are simpler than chaining map and filter with lambdas.
Complex is better than complicated
This is subtle. "Complex" means dealing with multiple interconnected parts. "Complicated" means confusing and hard to understand.
A system can be complex (many components) but not complicated (each component is clear). Choose complex-but-clear over simple-but-confusing.
For example, a well-designed class hierarchy might be complex, but if each class has a single responsibility and clear interfaces, it's not complicated.
Flat is better than nested
Deep nesting hurts readability. Flatten when possible.
# Nested
if condition1:
if condition2:
if condition3:
do_something()
# Flat
if not condition1:
return
if not condition2:
return
if not condition3:
return
do_something()
Guard clauses reduce nesting and make the logic linear.
Sparse is better than dense
Don't pack too much logic into one line. Give code room to breathe.
# Dense
return [[row[i] for row in matrix] for i in range(len(matrix[0]))]
# Sparse
transposed = []
for i in range(len(matrix[0])):
column = [row[i] for row in matrix]
transposed.append(column)
return transposed
The sparse version is longer but easier to understand.
Readability counts
Code is read more often than it's written. Optimize for readers, not writers.
Choose descriptive variable names. Add comments when necessary. Format consistently. Readability isn't optional—it's a design goal.
Special cases aren't special enough to break the rules
Consistency matters more than convenience. Don't add special behavior that violates established patterns.
Python itself follows this. Strings, lists, and tuples all support iteration the same way. There's no special-case syntax for strings—they're sequences like any other.
Although practicality beats purity
But sometimes you need to break the rules. Pragmatism wins when purity becomes an obstacle.
Python 2's print statement violated the "everything is an object" principle, but it was practical. Python 3 fixed this by making print() a function, but the years of print x showed practicality in action.
Errors should never pass silently
Make failures obvious. Don't suppress errors without good reason.
# Bad
try:
result = risky_operation()
except:
pass # Silent failure
# Good
try:
result = risky_operation()
except SpecificError as e:
logger.error(f"Operation failed: {e}")
raise
Bare except clauses hide bugs. Catch specific exceptions and handle them appropriately.
Unless explicitly silenced
But if you're intentionally ignoring an error, make it explicit:
try:
os.remove(temp_file)
except FileNotFoundError:
pass # File already gone, which is fine
The comment shows intent. You're not hiding an error—you're handling an expected condition.
In the face of ambiguity, refuse the temptation to guess
When behavior isn't clear, raise an error. Don't make assumptions.
Python's dynamic typing can create ambiguity. If a function receives unexpected input, it should fail clearly rather than guess at what was meant:
def process(data):
if not isinstance(data, list):
raise TypeError(f"Expected list, got {type(data)}")
# Process list
There should be one-- and preferably only one --obvious way to do it
Python aims for a single, clear solution to common problems. This contrasts with Perl's "there's more than one way to do it" philosophy.
For opening files, use with:
with open("file.txt") as f:
content = f.read()
You can use open() without with, but the with statement is the obvious, recommended way—it handles cleanup automatically.
Although that way may not be obvious at first unless you're Dutch
This is a joke about Guido van Rossum, Python's creator, who is Dutch. The "obvious" way isn't always immediately apparent. Learning Pythonic idioms takes time.
List comprehensions weren't obvious to newcomers in the 1990s. Now they're standard Python. The obvious solution emerges through learning.
Now is better than never
Don't wait for the perfect solution. Ship working code.
This encourages iteration over paralysis. Write code that works, then improve it.
Although never is often better than *right* now
But don't rush. If you're not ready, wait. A bad implementation can be worse than no implementation.
This tension—act now vs. wait—is deliberate. Use judgment.
If the implementation is hard to explain, it's a bad idea
If you can't explain how your code works in a few sentences, it's probably too complex.
Decorators, for example, have a simple explanation: "functions that modify other functions." If your decorator requires a lengthy explanation, it's doing too much.
If the implementation is easy to explain, it may be a good idea
"May be" is key. Simple explanations suggest good design, but they don't guarantee it. Simplicity is necessary, not sufficient.
Namespaces are one honking great idea -- let's do more of those!
Namespaces prevent name collisions. math.sqrt and numpy.sqrt can coexist because they're in different namespaces.
Python encourages namespaces through modules, classes, and functions. They're fundamental to organizing code.
The Missing Twentieth Principle
There are 19 principles, not 20. The missing one is deliberate—Tim Peters never wrote it. Speculation abounds, but the most common theory is that it's about maintaining a sense of incompleteness, acknowledging that no set of principles captures everything.
The Easter Egg Implementation
If you look at the source of this.py, you'll find the Zen is stored encrypted with ROT13:
s = """Gur Mra bs Clguba, ol Gvz Crgref..."""
The module decodes it when imported. This is a joke—encrypting Python's philosophy about simplicity and explicitness with a trivial cipher. Even the Zen doesn't take itself too seriously.
Living by the Zen
These aren't strict rules. They're guidelines that sometimes contradict each other. "Simple is better than complex" conflicts with "complex is better than complicated." That's intentional. Programming requires judgment.
The Zen helps you make better decisions, but it doesn't make decisions for you.
Further Reading
PEP 20, The Zen of Python, is the official specification.
For practical applications, see PEP 8, the Python style guide, which embodies many Zen principles.
Raymond Hettinger's talk "Beyond PEP 8" explores what makes code Pythonic, with heavy reference to the Zen.
The Zen of Python is short enough to memorize, but understanding it takes years of writing Python.
0 comments