How to write clean Python code using PEP 8?

Mohith Aakash G
featurepreneur
Published in
6 min readJan 15, 2022

PEP stands for Python Enhancement Proposal. It is a document that provides guidelines and best practices on how to write Python code. It was written in 2001 by Guido van Rossum (creator of Python), Barry Warsaw, and Nick Coghlan. The primary focus of PEP 8 is to improve the readability and consistency of Python code.

Why is PEP 8 important?

Code is read much more often than it is written.

— Guido Van Rossum

The code can be written in a few minutes, a few hours, or a whole day but once we have written the correct code, we probably will never rewrite it again. But sometimes, we need to read the code again and again.

At this point, we must have an idea of why we wrote the particular line in the code. The code should reflect the meaning of each line. That’s why readability is so much important.

Guidelines for writing effective Python code

Naming Conventions

  • class names should be CamelCase (OurClass)
  • variable names should be snake_case and all lowercase (last_name)
  • function names should be snake_case and all lowercase (merge_sort())
  • constants should be snake_case and all uppercase (PI = 3.14159)
  • modules should have short, snake_case names and all lowercase (numpy)
  • single quotes and double quotes are treated the same (choose one and use it consistently)

Choosing Names for identifiers

You should put a fair amount of thought into your naming choices when writing code as it will make your code more readable. The best way is to be as descriptive as possible.

>>> # Not recommended
>>> x = 'John Smith'
>>> y, z = x.split()
>>> print(z, y, sep=', ')
'Smith, John'
>>> def db(x):
>>> return x * 2

The above style might be okay for simple applications. But as the size of your project increases, trying to decode what the single letter variable means could be horrific.

>>> # Recommended
>>> name = 'John Smith'
>>> first_name, last_name = name.split()
>>> print(last_name, first_name, sep=', ')
'Smith, John'
>>> def double(x):
>>> return x * 2

Clearly the above style is more understandable.

Maximum Line Length and Line Breaking

PEP 8 suggests lines should be limited to 79 characters. This is because it allows you to have multiple files open next to one another, while also avoiding line wrapping.

Of course, keeping statements to 79 characters or less is not always possible. PEP 8 outlines ways to allow statements to run over several lines.

Python will assume line continuation if code is contained within parentheses, brackets, or braces:

def function(arg_one, arg_two,
arg_three, arg_four):
return arg_one

Line Break Before or After a Binary Operator?

The lines break before or after a binary operation is a traditional approach. But it affects the readability extensively because the operators are scattered across the different screens, and each operator is kept away from its operand and onto the previous line. Let’s understand the following example.

#Wrong:  
#operators sit far away from their operands
marks = (english_marks +
math_marks +
(science_marks - biology_marks) +
Physics_marks

As we can see the above code is hard to follow.

#Correct:  
#easy to match operators with operands
Total_marks = (English_marks
+ math_marks
+ (science_marks - biology_marks)
+ physics_marks

Python allows us to break line before or after a binary operator, as long as the convention is consistent locally.

Where to Put the Closing Brace

Line continuations allow you to break lines inside parentheses, brackets, or braces. It’s easy to forget about the closing brace, but it’s important to put it somewhere sensible. Otherwise, it can confuse the reader. PEP 8 provides two options for the position of the closing brace in implied line continuations:

  • Line up the closing brace with the first non-whitespace character of the previous line:
list_of_numbers = [
1, 2, 3,
4, 5, 6,
7, 8, 9
]
  • Line up the closing brace with the first character of the line that starts the construct:
list_of_numbers = [
1, 2, 3,
4, 5, 6,
7, 8, 9
]

You are free to chose which option you use. But, as always, consistency is key, so try to stick to one of the above methods.

Comments

Comments are the integral part of the any programming language. These are the best way to explain the code. When we documented our code with the proper comments anyone can able to understand the code. But we should remember the following points.

  • Start with the capital latter, and write complete sentence.
  • Update the comment in case of a change in code.
  • Limit the line length of comments and docstrings to 72 characters.

Block Comment

Block comments are the good choice for the small section of code. Such comments are useful when we write several line codes to perform a single action such as iterating a loop. They help us to understand the purpose of the code.

PEP 8 provides the following rules to write comment block.

  • Indent block comment should be at the same level.
  • Start each line with the # followed by a single space.
  • Separate line using the single #.

Let’s see the following code.

for i in range(0, 10):
# Loop i ten times and print out the value of i, followed by a
# new line character
print(i, '\n')

We can use more than paragraph for the technical code. Let’s understand the following example.

def quadratic(a, b, c, x):
# Calculate solution to a quadratic equation using the quadratic
# formula.
#
# A quadratic equation always has 2 solutions x_1 and x_2.
x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
return x_1, x_2

Inline Comments

Inline comments are used to explain the single statement in a piece of code. We can quickly get the idea of why we wrote that particular line of code. PEP 8 specifies the following rules for the inline comments.

  • Start comments with the # and single space.
  • Use inline comments carefully.
  • We should separate the inline comments on the same line as the statement they refer.

Below is an example of an inline comment:

x = 5  # This is an inline comment

Sometimes, inline comments can seem necessary, but you can use better naming conventions instead. Here’s an example:

x = 'John Smith'  # Student Name

Here, the inline comment does give extra information. However using x as a variable name for a person’s name is bad practice. There’s no need for the inline comment if you rename your variable:

student_name = 'John Smith'

Finally, inline comments such as these are bad practice as they state the obvious and clutter code:

empty_list = []  # Initialize empty listx = 5
x = x * 5 # Multiply x by 5

Inline comments are more specific than block comments, and it’s easy to add them when they’re not necessary, which leads to clutter. You could get away with only using block comments so, unless you are sure you need an inline comment, your code is more likely to be PEP 8 compliant if you stick to block comments.

Documentation Strings

Documentation strings, or docstrings, are strings enclosed in double (""") or single (''') quotation marks that appear on the first line of any function, class, method, or module.

The most important rules applying to docstrings are the following:

  • Surround docstrings with three double quotes on either side, as in """This is a docstring""".
  • Write them for all public modules, functions, classes, and methods.
  • Put the """ that ends a multiline docstring on a line by itself:
def quadratic(a, b, c, x):
"""Solve quadratic equation via the quadratic formula.

A quadratic equation has the following form:
ax**2 + bx + c = 0

There always two solutions to a quadratic equation: x_1 & x_2.
"""
x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)

return x_1, x_2
  • For one-line docstrings, keep the """ on the same line:
def quadratic(a, b, c, x):
"""Use the quadratic formula"""
x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)

return x_1, x_2

To learn more about PEP 8, visit pep8.org. Thank you for reading!

--

--