Code Style and PEP 8 Guidelines in Python

Author

Davide Vitiello, Mirai Solutions GmbH

Published

March 11, 2025

What is PEP 8?

PEP stands for Python Enhancement Proposal, a design document providing information to the Python community, or describing a new feature for Python or its processes. PEP 8, in particular, is Python’s style guide, namely a set of rules that specify how to format Python code for maximum readability.

Python’s philosophy emphasizes readability, which is one of the key reasons for its widespread adoption. Readability has guided the development of Python’s style guide, known as PEP 8. In this section, we outline some of the PEP 8 guidelines and show how they affect the writing of clean & professional Python code.

Key PEP 8 Guidelines

Indentation

Python uses indentation to define blocks of code. In other words, the Python interpreter assigns a semantic value to indentation. This is different from other programming languages where indentation has solely an aesthetic role, as e.g. in C++.
1 space represents the minimum discriminant between two different levels of indentation, although PEP 8 recommends using 4 spaces per indentation level to ensure consistency and readability across various text editors and development environments.

# ugly but legitimate indentation

def foo():
 print("Hello, World!")
foo()
Hello, World!
# best practice

def foo():
    print("Hello, World!")
foo()
Hello, World!

For sake of comparison, in C++ and in most of other programming languages, the { and } parentheses wrapping around a block of code define its scope, so the indentation doesn’t affect the program’s logic.

#include <iostream>
using namespace std;

void foo() {
    cout << "Hello, World!" << endl;
}

foo()

The code above works exactly like the one below:

#include <iostream>
using namespace std;

void foo() {
cout << "Hello, World!" << endl;
}

foo()

On the contrary, in Python, incorrect indentation can lead to errors or unintended behavior. For example:

def foo():
# Incorrectly indented
print("Hello, World!")
  Cell In[3], line 3
    print("Hello, World!")
    ^
IndentationError: expected an indented block after function definition on line 1

Maximum Line Length

Lines should not exceed 79 characters to ensure code readability and compatibility with various devices and editors. For longer expressions, one must use line breaks. Tools like Flake8 can be employed to enforce this limit and help maintain code quality.

Blank Lines

Blank lines must be used to separate functions and classes, and within classes to separate methods. This helps in visually organizing the code and making it easier to navigate.

def function_one():
    pass


def function_two():
    pass


class MyClass:
    def method_one(self):
        pass

    def method_two(self):
        pass


class AnotherClass:
    def method_a(self):
        pass

    def method_b(self):
        pass

Imports

Imports are to be grouped into three categories: standard library modules, third-party modules, and your own modules. Each group should be placed in separate blocks, sorted alphabetically. The module isort automatizes said task.

import os
import sys

from third_party import third_party_library

from . import calc

Whitespace Character in Expressions and Statements

Extraneous whitespace characters are to be avoided in the following situations:

  • Immediately inside parentheses, brackets, or braces.
  • Between a trailing comma and a following close parenthesis.
  • Immediately before a comma, semicolon, or colon.
# Correct use of whitespace
spam(ham[1], {eggs: 2})
# Incorrect use of whitespace
spam( ham[1], {eggs: 2} )
spam( ham[1] , {eggs: 2} )
spam( ham[1] , { eggs: 2 } )

Automatic reformatting can be achieved using linters like Black.

Comments

Comments should be complete sentences. If a comment is a phrase or sentence, its first word should be capitalized, unless it’s an identifier that begins with a lower-case letter.

Naming Conventions

One should stick to the convention of using CamelCase for classes and snake_case for functions and variables.

class MyClassName:
    def my_function_name(variable_name):
        pass

Usage of descriptive naming styles for variables, functions, classes, and modules should be in place. Avoidance of names that are too vague or too verbose is preferable.

# Too vague
def calc(p, t):
    return p + (p * t)

# Too verbose
def calculate_total_price_in_the_case_of_increased_inflation_from_previous_quarter(price, tax_rate):
    return price + (price * tax_rate)

# More descriptive and concise
def calculate_total_price(price, tax_rate):
    return price + (price * tax_rate)

Libraries for PEP 8 Compliance

Integrating the list of briefly mentioned formatting tools, the following tools can help one adhere to PEP 8 guidelines, including:

  • Flake8: checks the code against PEP 8 and other style guides.
  • Pylint: analyzes the code for errors and adherence to coding standards.
  • Black: an opinionated formatter that automatically adjusts your code to conform to PEP 8 standards.
  • isort: order import statements
  • Ruff: a fast Python linter and code formatter written in Rust. It provides better performance than Flake8 and Black, drop-in parity with Flake8, isort, and Black. Integrating these tools at once into the development process enhances code quality and ensures consistency across projects.
Back to top