5.2. PEP 8 style guidelines#

As touched upon in a previous chapter, there is a set of guidelines intended to improve the readability of code and make it consistent across the wide spectrum of Python code: the PEP 8 – Style Guide for Python Code. You can find the full text of the guide at this webpage. Here, we will summarize some of the most essential parts, which you should implement in your own coding.

Some recommendations will become more relevant later, e.g., when we learn about flow control and functions. However, we’re summarizing all recommendations here for the sake of completeness.

Note: you don’t have to run the code lines on this page as they are just intended to demonstrate good and bad practices in styling Python code.

5.2.1. Code layout#

5.2.1.1. Indentation#

Indentations are very important in Python. To indent, you can use either spaces or Tab, with the former being preferred.

Use four spaces per indentation level. Note: IDE does this automatically for you when it recognizes the need for indentation.

# Correct
# The closing brace/bracket/parenthesis on multiline constructs may either line up under the first non-whitespace character 
# of the last line of list, as in:
my_list = [
    1, 2, 3,
    4, 5, 6,
    ]

# or it may be lined up under the first character of the line that starts the multiline construct, as in:
my_list = [
    1, 2, 3,
    4, 5, 6,
]

# Continuation line aligned with opening delimiter
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

5.2.1.2. Line length#

Limit lines to a maximum of 79 characters and comment lines to 72 characters. This makes it possible to have several files open side by side, and works well when using code review tools.

The preferred way of wrapping long lines is by using Python’s implied line continuation inside parentheses. Backslashes may also be appropriate at times.

with open('/path/to/some/file/you/want/to/read') as file_1, \
     open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())

5.2.1.3. Line breaks and binary operators#

For easier readability, the line break should come before binary operators. This makes it easy to match operators with operands.

# Correct:
# easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends))


# Wrong:
# operators sit far away from their operands
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends))

5.2.1.4. Blank lines#

Surround top-level function definitions with two blank lines. Use blank lines in functions, sparingly, to indicate logical sections. Blank lines may be omitted between a lot of related one-liners.

For imports, each import should be in a separate line:

# Correct:
import os
import sys

# Wrong:
import sys, os

5.2.2. String quotes#

In Python, single (’ ‘) and double (” “) quoted strings are the same. There is no recommendation for one over the other, so you can pick one and stick to it. When a string contains single or double quotations, however, use the other one to avoid backslashes in the string.

# Correct
my_string = "I have a 'quote' inside a string."

# Not as nice for readability. Here we have to use \ for string to recognize " inside the string as just a character
my_string = "I have a \"quote\" inside a string."

5.2.3. Whitespace#

Avoid extraneous whitespace in the following situations:

  • Immediately inside parentheses, brackets or braces:

# Correct:
spam(ham[1], {eggs: 2})

# Wrong:
spam( ham[ 1 ], { eggs: 2 } )
  • Between a trailing comma and a subsequent closed parenthesis:

# Correct:
foo = (0,)

# Wrong:
bar = (0, )
  • Immediately before a comma, semicolon, or colon:

# Correct:
if x == 4: print(x, y); x, y = y, x

# Wrong:
if x == 4 : print(x , y) ; x , y = y , x
  • However, in a slice the colon should have equal amounts of space on either side:

# Correct:
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]

# Wrong
ham[1: 9], ham[1 :9], ham[1:9 :3]
  • Immediately before the open parenthesis that starts the argument list of a function call or that starts an indexing or slicing:

# Correct:
spam(1)
dct['key'] = lst[index]

# Wrong:
spam (1)
dct ['key'] = lst [index]
  • More than one space around an assignment (or other) operator to align it with another:

# Correct:
x = 1
y = 2
long_variable = 3

# Wrong:
x             = 1
y             = 2
long_variable = 3

If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator:

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


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

5.2.4. Comments#

Comments that contradict the code are worse than no comments. Always make a priority of keeping the comments up-to-date when the code changes!

Comments should be complete sentences. The first word should be capitalized, unless it is an identifier that begins with a lowercase letter.

Ensure that your comments are clear and easily understandable to other speakers of the language you are writing in. Write your comments in English.

5.2.4.1. Inline comments#

An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space.

Use inline comments sparingly.

Inline comments are unnecessary and in fact distracting if they state the obvious:

# Distracting and useless
x = x + 1                 # Increment x


# An example of a useful inline comment
x = x + 1                 # Compensate for border

5.2.5. Naming#

5.2.5.1. Function and variable names#

Function names should be lowercase, with words separated by underscores as necessary to improve readability (e.g., function_doing_something).

Variable names follow the same convention as function names. Never use the characters ‘l’ (lowercase letter L), ‘O’ (uppercase letter O), or ‘I’ (uppercase letter I) as single character variable names. In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use ‘l’, use ‘L’ instead.

5.2.6. Programming recommendations#

  • Use ''.startswith() and ''.endswith() instead of string slicing to check for prefixes or suffixes. startswith() and endswith() are cleaner and less error prone:

# Correct:
if foo.startswith('bar'):

# Wrong:
if foo[:3] == 'bar':
  • For sequences (strings, lists, tuples), use the fact that empty sequences are false:

# Correct:
if not seq:
if seq:

# Wrong:
if len(seq):
if not len(seq):
  • Don’t compare Boolean values to True or False using ==:

# Correct:
if greeting:

# Wrong:
if greeting == True:

# Worse:
if greeting is True: