PEP 8 - Guide to Beautiful Python Code

PEP 8 - Guide to Beautiful Python Code


What is PEP?

PEP stands for Python Enhancement Proposal. A PEP is a design document providing information to the Python community, or describing a new feature for Python or its processes or environment.

An Introduction to PEP 8?

PEP 8, also called Style Guide for Python Code, gives coding conventions for the Python code comprising the standard library in the main Python distribution. 

Creator of Python Guido van Rossum's key insights is that code is read much more often than it is written. So as PEP 8 he, along with Barry Warshaw and Nick Coghlan, provided guidelines on how to write readable code in Python.


Indentation is necessary in Python. However the number of indented spaces and whether to use Tab or Space depends on the developer. However, to make code readable consistency is important. So, PEP 8 suggests to use 4 spaces per indentation level.

For eg.: The below lines of code demonstrate 4 spaces for indentation.

if True: print("There are 4 indentation spaces.") for i in range(5): print("Again, 4 indentation spaces.")

Also, it is suggested to keep less than 79 characters in a line. So, in the case where big expressions are necessary to write, it is suggested to use hanging indent. When using a hanging indent there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line.

For eg.: The below lines of code demonstrate hanging indents.

def very_long_function_name( first_argument, second_argument, third_argument, fourth_argument): print("Hanging indent.") # function call very_long_function_name( first_argument, second_argument, third_argument, fourth_argument)

Blank Lines

Python scripts surround top-level function and class definitions with two blank lines. Method definitions inside a class are surrounded by a single blank line. We can also use blank lines in functions to indicate logical sections. Use of blank lines other than this should be prevented.

For eg.: The below lines of code demonstrate how to use blank lines.

class One: def first_method(self): print('This is the first method.') def second_method(self): print('This is the second method.') def third_method(self): print('This is the third method.') class Two: def first_method(self): print('This is the first method.') def second_method(self): print('This is the second method.') def third_method(self): print('This is the third method.') def func(): print('This is a function.') if __name__ == '__main__': func() obj1 = One() obj2 = Two() obj1.first_method() obj2.second_method()


Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

Imports should be grouped in the following order:

  1. Standard library imports.

  2. Related third party imports.

  3. Local application/library specific imports.

We should put a blank line between each group of imports.

Imports should usually be on separate lines.

For eg.: This should be avoided.

import os, sys

And this should be preferred.

import os import sys

The below can also be done.

from subprocess import Popen, PIPE

Wildcard imports (from subprocess import *) should be avoided, as they make it unclear which names are present in the code.

String Quotes

In Python, single-quoted strings and double-quoted strings are the same. PEP 8 does not make a recommendation on what to use. When a string contains single or double quote characters use the other one to avoid backslashes in the string.

For triple-quoted strings, always use double quote characters to be consistent with the docstring convention.

Whitespaces in Expressions and Statements

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 following close parenthesis:

# Correct: foo = (0,) # Wrong: foo = (0, )

  • Immediately before the open parenthesis that starts the argument list of a function call:

# Correct: spam(1) # Wrong: spam (1)

  • Immediately before the open parenthesis that starts an indexing or slicing:

    # Correct: dct['key'] = lst[index] # Wrong: 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

  • Always surround following binary operators with a single space on either side:

assignment (=), augmented assignment (+=, -= etc.), comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not), booleans (and, or, not).

  • If operators with different priorities are used, consider adding whitespace around the operators with the lowest priorities.

# 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)

  • Don't use spaces around the = sign when used to indicate a keyword argument, or when used to indicate a default value for an unannotated function parameter:

# Correct: def complex(real, imag=0.0): return magic(r=real, i=imag) # Wrong: def complex(real, imag = 0.0): return magic(r = real, i = imag)

  • Compound statements (multiple statements on the same line) are generally discouraged:

# Correct: if foo == 'blah': do_blah_thing() do_one() do_two() do_three() # Wrong: if foo == 'blah': do_blah_thing() do_one(); do_two(); do_three()


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

Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period.

Naming Conventions

Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single character variable names.

In some fonts, these characters are indistinguishable from the numerals one and zero.

Identifiers must be ASCII compatible.

Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability.

Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.

Class names should normally use the CapWords convention.

Function names should be lowercase, with words separated by underscores as necessary to improve readability.

Variable names follow the same convention as function names.

Always use 'self' for the first argument to instance methods.

Constants are usually defined on a module level and written in all capital letters with underscores separating words.


One of the main reasons for the gaining popularity of Python is the readability of code. So, it is a duty of us as developers to take care about the code quality and readability. PEP 8 does not describe rules to write code but mere conventions, so we have flexibility to not ignore PEP 8 in some cases. However, we should try to follow it and make it a part of our develop-staging-test-deploy cycle. This benefits everyone working on the project to understand and most of the time making changes in the code can be done without digging deep. It will also help a lot if we are contributing on an open-source project, as PEP 8 is the universal standard and each Python developer follows this.

More Articles of Aniket Sharma:

Name Views Likes
Pyperclip: Installation and Working 1131 2
Number Guessing Game using Python 768 2
Pyperclip: Not Implemented Error 1546 2
Hangman Game using Python 20008 2
Using Databases with CherryPy application 2273 2
nose: Working 601 2
pytest: Working 600 2
Open Source and Hacktoberfest 981 2
Managing Logs of CherryPy applications 1177 2
Top 20 Data Science Tools 787 2
Ajax application using CherryPy 930 2
REST application using CherryPy 777 2
On Screen Keyboard using Python 8409 2
Elastic Net Regression 1008 2
US Presidential Election 2020 Prediction using Python 877 2
Sound Source Separation 1376 2
URLs with Parameters in CherryPy 2267 2
Testing CherryPy application 766 2
Handling HTML Forms with CherryPy 1908 2
Applications of Natural Language Processing in Businesses 605 2
NetworkX: Multigraphs 875 2
Tracking User Activity with CherryPy 1664 2
CherryPy: Handling Cookies 1201 2
Introduction to NetworkX 715 2
TorchServe - Serving PyTorch Models 1539 2
Fake News Detection Model using Python 839 2
Keeping Home Routers secure while working remotely 567 2
Email Slicer using Python 3167 2
NetworkX: Creating a Graph 1207 2
Best Mathematics Courses for Machine Learning 644 2
Hello World in CherryPy 960 2
Building dependencies as Meson subprojects 1235 2
Vehicle Detection System 1223 2
NetworkX: Examining and Removing Graph Elements 704 2
Handling URLs with CherryPy 626 2
PEP 8 - Guide to Beautiful Python Code 860 2
NetworkX: Drawing Graphs 739 2
Mad Libs Game using Python 757 2
Hosting Cherry applications 714 2
Top 5 Free Online IDEs of 2020 993 2
pytest: Introduction 612 2
Preventing Pwned and Reused Passwords 658 2
Contact Book using Python 2330 2
Introduction to CherryPy 636 2
nose: Introduction 574 2
Text-based Adventure Game using Python 3487 2
NetworkX: Adding Attributes 3242 2
NetworkX: Directed Graphs 1245 2
Dice Simulator using Python 659 2
Decorating CherryPy applications using CSS 1034 2