Last modified on 01 Oct 2021.

What’s PEP 8?

It contains some conventions in coding with Python. They make the codes clearer and more beautiful. Read the full doc here. Below are just some of them in my choice.

Naming styles

  • Package & module names & function & variable: all_lower_case or short with underscore.
  • Class names: use CapWords.
  • Constant: ALL_CAPITAL_LETTERS.
  • Avoid these:

    l = 1 # lowercase letter el
    O = 1 # uppercase letter oh
    I = 1 # uppercase letter eye
    
    Capitalized_Words_With_Underscores = 1 # ugly
    

Code layout

Indentation

Use 4 spaces per indentation level. Note that, in this site, for a better view, I use 2 spaces for the code highlight.

# YES
def func(...):
    commands # 4 spaces
# NO
def func(...):
  commands # 2 spaces

Vertical align when break a continuous line:

# YES
foo = long_function_name(var_one, var_two,
                         var_three, var_four)
# NO
foo = long_function_name(var_one, var_two,
    var_three, var_four)

Distinguish arguments from the rest:

# YES
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)
# NO
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

Tabs or spaces?

Spaces are preferred. Don’t mix tabs and spaces (not allowed in Python 3).

Max line lenght

Max of 79 characters.

Line break with operator

Operators should go with operands

# YES
income = (salary
          + sale)
# NO
income = (salary +
          sale)

Import

Imports should usually be on separate lines:

# YES
import os
import sys
# NO
import os, sys
# But yes
from subprocess import Popen, PIPE

Whitespace

Avoid extraneous whitespace:

# YES
spam(ham[1], {eggs: 2})
foo = (0,)
if x == 4: print x, y; x, y = y, x
# NO
spam( ham[ 1 ], { eggs: 2 } )
bar = (0, )
if x == 4 : print x , y ; x , y = y , x

For slices

# YES
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
# NO
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]

Add open parenthesis/bracket right after:

# YES
spam(1)
dct['key'] = lst[index]
# NO
spam (1)
dct ['key'] = lst [index]

No need to have verticle alignment:

# YES
x = 1
y = 2
long_variable = 3
# NO
x             = 1
y             = 2
long_variable = 3

With operators:

# YES
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
# NO
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)

Def of a function:

# YES
def complex(real, imag=0.0):
    return magic(r=real, i=imag)
# NO
def complex(real, imag = 0.0):
    return magic(r = real, i = imag)

Programming Recommendations

Using not inside if:

# YES
if foo is not None:
# NO
if not foo is None:

Using Use .startswith() and .endswith() instead of string slicing:

# YES
if foo.startswith('bar'):
# NO
if foo[:3] == 'bar':

For sequences, (strings, lists, tuples), use the fact that empty sequences are false:

# YES
if not seq:
if seq:
# NO
if len(seq):
if not len(seq):

Don’t compare boolean values to True or False using ==:

# YES
if greeting:
# NO
if greeting == True:
# Worse
if greeting is True: