The attitude that programmers should have (The Zen of Python)

Introduction

This article is on stackoverflow's Questions and Answers about The Zen of Python (CC BY-SA3.0 License). The Japanese translation of The Zen of Python was based on "What are we looking for in" Python "?". ..

What is The Zen of Python?

The Zen of Python is a concise summary of the attitudes Python programmers should have. This should be of great help to programmers who don't write Python. By the way, "Zen" is Japanese "Zen".

You don't have to try to read the full text from the beginning. We encourage you to take a quick look at this article and read the parts that interest you.

The full text is on the Python interpreter

>>> import this

You can display it by typing.

The full text is below.

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Beautiful is better than ugly.

Explicit is better than implicit.
It is better to clarify than to imply.

Simple is better than complex.
It's better to be plain than complicated.

Complex is better than complicated.
Still, it's better to be complicated than complicated.

Flat is better than nested.
The nest should be shallow.

Sparse is better than dense.
It's better to have a gap than to be crowded.

Readability counts.
Easy to read is good.

Special cases aren't special enough to break the rules.
Being special is not a reason to break the rules.

Although practicality beats purity.
However, when it comes to practicality, purity can be lost.

Errors should never pass silently.
Don't hide the error, don't ignore it.

Unless explicitly silenced.
However, if it is hidden on purpose, don't miss it.

In the face of ambiguity, refuse the temptation to guess.
If you come across something ambiguous, don't guess what it means.

There should be one-- and preferably only one --obvious way to do it.
There must be some good way. There is only one way that is obvious to everyone.

Although that way may not be obvious at first unless you're Dutch.
The method may be difficult to understand at first glance. It may be easy to understand only for Dutch people.

Now is better than never.
Do it now, rather than not doing it all the time.

Although never is often better than *right* now.
But now"soon"It's often better not to do it than to do it.

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

If the implementation is easy to explain, it may be a good idea.
If you can easily explain the content of the code, it's probably a good implementation.

Namespaces are one honking great idea -- let's do more of those!
Namespaces are a great idea and should be actively used.

Commentary

Then, I will explain the original text line by line.

Beautiful is better than ugly. Beautiful is better than ugly.

Example

(Respondent: J.T. Hurley)

With Python, you can find the greatest common divisor with just this much code.

def gcd(x, y):
    while y:
        x, y = y, x % y
    return x

The more beautiful the algorithm, the more beautiful the code. And Python can express its beauty with a small number of lines.

Explicit is better than implicit. It is better to clarify than to imply.

Example 1

Don't do this.

from os import *
print(getcwd())

Make it easy to see from which module the function is provided.

import os
print(os.getcwd())

The Zen of Python says:

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

Namespaces are a great idea.

Therefore, in Python, when calling a method, when referencing a field, specify self even in the class. Programmers should always be aware of what and where the objects they are using are.

Example 2

Some scripting languages can do this.

test.php


<?php
$foo = "5";
echo $foo * 3;
?>

When executed, it becomes like this.

$php test.php 
15

This happens because the character string is regarded as an integer when the operation of character string x integer is performed. It's called implicit type conversion. But in Python I get an error like this:

>>> foo = "5"
>>> foo+3
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

If you want the result to be returned as an integer, you need to specify it.

>>> int(foo)+3
8

Simple is better than complex. It's better to be plain than complicated.

Complex is better than complicated. Still, it's better to be complicated than complicated.

Example

Referenced page: What does “Complex is better than complicated” mean? (Respondent: EinLama)

Being complicated or esoteric is a little different from being complicated.

Let's take this code as an example.

counter = 0
while counter < 5:
   print(counter)
   counter += 1

This code should be very easy to understand. But this code is esoteric. Two elements, "managing counter variables" and "displaying values with print statements", are mixed up in one code.

for i in xrange(5):
   print(i)

On the other hand, this code is more complex than the example using wihle. There is a clear separation between the two elements of "counter variable management" and "printing the value". If you don't know xrange, you may not know what this code is doing. But if you want to write clean code, the cost of finding out what xrange is isn't that great. You can easily understand how xrange works by reading the documentation.

The larger the code, the greater the difference in manageability between esoteric code and complex code. Of course, the simpler and easier to write, the easier it is to manage.

Beautiful is better than ugly.



Flat is better than nested.
 The nest should be shallow.

### Example
 (Respondent: [S.Lott](https://stackoverflow.com/users/10661/s-lott))

 For example, the classes provided by Java and C ++ libraries usually inherit from other classes.
 When this happens, you have to think about how the class you want to use inherits from other classes.
 Therefore, it becomes difficult to properly understand and use the library specifications.

 But with Python, you don't have to write __com.company.java.blah.blah__ when using standard modules. Most of the time it should be __timeit__ or __csv__. This is possible because the namespace is built flat.

 Sparse is better than dense.
 It's better to have a gap than to be crowded.

### Example
```python 
if i>0: return sqrt(i)
elif i==0: return 0
else: return 1j * sqrt(-i)
if i > 0:
    return sqrt(i)
elif i == 0:
    return 0
else:
    return 1j * sqrt(-i)

Which is easier to read, the code above or the code below?

Don't try to pack too much into one line.

Readability counts. Easy to read is good.

Example

(Respondent: Federico A. Ramponi)

Let's compare C and Python.

#include <stdio.h>
int main(void) {
    printf("Hello, world!\n");
    return(0);
}
print("Hello, world!")

Even with the same "Hello, World!", The readability is completely different between C and Python. With Python, you can see at a glance what your code is doing.

Special cases aren't special enough to break the rules. Being special is not a reason to break the rules.

Although practicality beats purity. However, when it comes to practicality, purity can be lost.

Example

(Respondent: Federico A. Ramponi)

Python doesn't have a "character-only" type like char. It's not as special as it needs a special mold. However, in pursuit of practicality, a function that takes or returns a character of length 1 such as chr or ord is required.

Errors should never pass silently. Don't hide the error, don't ignore it.

Example

(Respondent: Ali Afshar)

For example, don't write this code.

try:
    import this
except ImportError:
    pass

Make it clear that an error has been detected.

try:
    import this
except ImportError:
    print('this is not available')

Unless explicitly silenced. However, if it is hidden on purpose, don't miss it.

Example

(Respondent: Ali Afshar)

Let's take a look at this code.

d = dict((('spam', 1), ('ham', 2)))

default = 0
k = 'eggs'

try:
    v = d[k]
except KeyError:
    v = d[k] = default

print("v:{}".format(v))
print("d:{}".format(d))

When executed, it becomes like this.

$python silenced.py 
v:0
d:{'eggs': 0, 'ham': 2, 'spam': 1}

This code sets the key to a default value when it doesn't exist. The except clause does not notify the outside that an error has occurred. Because I do that on purpose.

In the face of ambiguity, refuse the temptation to guess. If you come across something ambiguous, don't guess what it means.

Example

When will this conditional statement be true?

if not a and b:
    pass

Rewrite it like this

if b and not a:
   pass

Or it's a little clunky, but it's better to write:

if (not a) and b:
    pass

There should be one-- and preferably only one --obvious way to do it. There must be some good way. There is only one way that is obvious to everyone.

Example

(Respondent: Federico A. Ramponi)

There are various ways to look at the elements of an array in order in C ++, depending on the type. (I'm not familiar with C ++ so please let me know if you have a good example)

But with Python, that's all you need. It doesn't matter if the target is a dictionary or a list, everything is fine in this way.

for element in sequence:

Although that way may not be obvious at first unless you're Dutch. The method may be difficult to understand at first glance. It may be easy to understand only for Dutch people.

About the Dutch

"Dutch" here refers to Python developer Guido van Rossum. See here for more information. I want it.

Example

(Respondent: S.Lott)

There was a heated debate about the if-then-else clause (cond? Expr1: expr2 in C). In it Guido proposed this.

a = expr1 if cond else expr2

This is the only way to write an if-then-else clause in Python. However, it is difficult to understand at first glance.

Now is better than never Do it now, rather than not doing it all the time.

Example

(Respondent: wim)

never

f = open('stay_open.txt', 'w')
f.write('every even number > 2 is the sum of two primes')
raise AssertionError('this sentence is false')
f.close()

now

with open('will_be_closed.txt', 'w') as f:
    f.write('the sum of two primes > 2 is an even number')
    raise AssertionError('this sentence is false')

Did you notice what's wrong with the never code? The never code will assert the connection to the file without closing it. The idea of "because I'll close it later" gives rise to bad code. However, the now code will close the connection to the file properly even if an error occurs.

The never code can also be rewritten as:

try:
    f = open('will_be_closed.txt', 'w')
    f.write('every even number > 2 is the sum of two primes')
    assert not 'this sentence is false'
finally: 
    f.close()

But beautiful is better than ugly.

Beautiful is better than ugly.

Although never is often better than right now. But it's often better not to do it now than to do it "immediately".

Example

Over-optimizing your code early on can often be a waste of time.

For example, if you need to implement sorting, you often don't need to implement quicksort from scratch. Quicksort is generally more difficult to implement than bubble sort. In reality, bubble sort is a sufficient problem, but writing with quick sort from the beginning is a waste of time. At the test stage, use bubble sort for the time being, and rewrite it to quicksort when necessary.

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

If the implementation is easy to explain, it may be a good idea. If you can easily explain the content of the code, it's probably a good implementation.

Namespaces are one honking great idea -- let's do more of those! Namespaces are a great idea and should be actively used.

Example

(Respondent: Federico A. Ramponi, Editor: wim)

When using the module, write like this.

import module
module.spam()

import module
breakfast = module.SpamAndEggs()

Don't write this.

from module import *

You can write this only when testing a function in a terminal. If you write this in a normal program, the names may conflict. Also, readability is reduced because you do not know which module the function belongs to.

If the module name or class name is long, you can use as.

import aRidiculouslyLongModuleName as short

Finally

If you have any questions or concerns, please comment.

List of reference materials

The Zen of Python What are we looking for in "Python"? What does “Complex is better than complicated” mean? An Introduction to the Zen of Python

Recommended Posts

The attitude that programmers should have (The Zen of Python)
the zen of Python
Note that Python decorators should have wraps
Japanese translation: PEP 20 --The Zen of Python
From a book that makes the programmer's way of thinking interesting (Python)
[Python] A program that counts the number of valleys
[Python] A program that compares the positions of kangaroos.
Towards the retirement of Python2
About the ease of Python
About the features of Python
The Power of Pandas: Python
Have the equation graph of the linear function drawn in Python
Consideration for Python decorators of the type that passes variables
A Python script that compares the contents of two directories
The specifications of pytz have changed
The story of Python and the story of NaN
[Python] The stumbling block of import
First Python 3 ~ The beginning of repetition ~
A story that struggled to handle the Python package of PocketSphinx
Existence from the viewpoint of Python
pyenv-change the python version of virtualenv
From a book that programmers can learn (Python): Find the mode
From a book that programmers can learn ... (Python): Review of arrays
Change the Python version of Homebrew
A function that measures the processing time of a method in python
This and that of python properties
Have python read the command output
[Python] Understanding the potential_field_planning of Python Robotics
Review of the basics of Python (FizzBuzz)
Verification of the theory that "Python and Swift are quite similar"
About the basics list of Python basics
[python] A note that started to understand the behavior of matplotlib.pyplot
The story of making a module that skips mail with python
[Python] A program that rotates the contents of the list to the left
[python] Script that (should) update pwsh
Learn the basics of Python ① Beginners
Python patterns that have been released to the world and have been scrutinized later
[Python] A program that calculates the number of chocolate segments that meet the conditions
Have Alexa run Python to give you a sense of the future
[Python] A program that calculates the number of socks to be paired
The module that should have been installed with pip does not run
Find out the name of the method that called it from the method that is python
[Python] Note: A self-made function that finds the area of the normal distribution
[python] Move files that meet the conditions
Change the length of Python csv strings
Check the behavior of destructor in Python
This and that of the inclusion notation.
[Python3] Understand the basics of Beautiful Soup
Pass the path of the imported python module
The story of making Python an exe
Learning notes from the beginning of Python 1
Check the existence of the file with python
About the virtual environment of python version 3.7
Python3 + pyperclip that rewrites the copied text
[Python] Understand the content of error messages
I didn't know the basics of Python
The result of installing python in Anaconda
[Python] Try pydash of the Python version of lodash
[python] Checking the memory consumption of variables
Check the path of the Python imported module
The story of manipulating python global variables