Skip to main content

Command Palette

Search for a command to run...

Visual PEP8

Published
5 min read
Visual PEP8
A

Andrew Stepin is a Technical Writer, Product Manager, and Blog Author. He writes code and educational documentations outside of his job. His interests include deep learning and NLP, with occasional forays into adjacent topics.

Andrew Stepin is associated with TensorFlow, having written articles highlighted at TensorFlow Dev Summit 2019 and contributed to the TensorFlow documentation repository. He is also a product manager, with a focus on SaaS, AI and machine learning.

Andrew Stepin is active on various platforms, including GitHub, where he maintains several repositories related to TensorFlow and machine learning, such as Bootstrap ML and TensorFlow Docs. He is also active on Twitter, where he shares updates and insights related to his projects.

Andrew Stepin's work is centered around making machine learning and deep learning more accessible and understandable to a broader audience. His contributions to TensorFlow and other projects aim to facilitate learning and experimentation in these fields.

1. Code Lay-out

1.1 Indentation

Use 4 spaces per indentation level.

def indented_function():
    pass

1.2 Maximum Line Length

Limit all lines to a maximum of 79 characters.

very_long_variable_name = 'This is a very long string that exceeds the maximum line length.'

1.3 Blank Lines

Surround top-level function and class definitions with two blank lines. Method definitions inside a class are surrounded by a single blank line.

class MyClass:
    """
    This is a class docstring.
    """

    def __init__(self):
        pass

    def method1(self):
        pass

    def method2(self):
        pass

def top_level_function():
    pass

1.4 Source File Encoding

Code in the core Python distribution should always use UTF-8 (or ASCII in Python 3).

1.5 Imports

Imports should be grouped in the following order:

  1. Standard library imports

  2. Related third-party imports

  3. Local application/library specific imports

import sys
import os
import re

import numpy as np
import pandas as pd

import mymodule

2. Whitespace in Expressions and Statements

2.1 Pet Peeves

Avoid extraneous whitespace in the following situations:

spam(ham[1], {eggs: 2})  # No whitespace after opening parentheses or before closing parentheses.
foo = (0,)  # No whitespace after the opening parenthesis or before the closing parenthesis.

2.2 Other Recommendations

Avoid trailing whitespace anywhere. Always surround binary operators with a single space on either side.

income = (gross_wages +
           taxable_interest +
           (dividends - qualified_dividends) -
           ira_deduction -
           student_loan_interest)

3. Naming Conventions

3.1 Descriptive Names

Use descriptive and meaningful names for variables, functions, and classes.

employee_name = 'John Doe'

def calculate_payroll(hours_worked, hourly_rate):
    pass

class EmployeeRecord:
    pass

3.2 Naming Styles

Follow the naming styles for different types of identifiers:

  • Functions and variables: lowercase_with_underscores

  • Classes: CapitalizedWords (CapWords)

  • Constants: CAPITALIZED_WITH_UNDERSCORES

  • Module-level constants: ALL_CAPS

MAX_EMPLOYEES = 100
__PRIVATE_CONSTANT__ = 42


class Employee:
    employee_count = 0

    def __init__(self, name):
        self.name = name
        Employee.employee_count += 1

    def display_employee_info(self):
        print(f"Employee Name: {self.name}")

4. String Quotes

4.1 String Quotes

Use single quotes for strings, or double quotes for strings with internal single quotes.

single_quoted_str = 'This is a single-quoted string.'
double_quoted_str = "This string has 'single quotes' inside."

4.2 Triple-Quoted Strings

Use triple double quotes for multiline strings and docstrings.

triple_quoted_str = """This is a
multiline string
with triple double quotes."""


def my_function():
    """
    This is a docstring for my_function.
    It spans multiple lines.
    """
    pass

5. Expressions and Statements

5.1 Whitespace in Expressions and Statements

Avoid extraneous whitespace in expressions and statements.

result = income + (interest - expenses)
values = [1, 2, 3]
x = 5
y = 6
complex = x + y

5.2 Compound Statements

When using compound statements, put each part on a separate line.

if x == 4: print(x, "is equal to 4"); x = x + 1
if y > 3 and \
   x < 10:
    print("This is a valid condition")

6. Programming Recommendations

6.1 Function Annotations

Use function annotations to document function parameters and return values.

def annotated_function(param1: int, param2: str) -> bool:
    """
    This function takes an integer and a string as input and returns a boolean.
    """
    pass

6.2 Type Comments

Use type comments to document complex types or types that cannot be expressed with annotations.

def complicated_function(param: 'MyClass or None') -> 'Union[int, str]':
    """
    This function takes an instance of MyClass or None as input and returns either an integer or a string.
    """
    pass

6.3 String Formatting

Use formatted string literals (f-strings) for string formatting.

name = "John"
age = 30
message = f"{name} is {age} years old."

6.4 Comprehensions

Use list, dict, and set comprehensions for concise and readable code.

squares = [x ** 2 for x in range(10)]
even_squares = {x ** 2 for x in range(10) if x % 2 == 0}
name_counts = {name: len(name) for name in names}

6.5 Generators

Use generators for efficient iteration over large or infinite sequences.

def fibonacci_generator():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

7. Comments and Docstrings

7.1 Comments

Use comments sparingly and only when necessary for code clarity. Avoid redundant comments that simply restate the code.

x = x + 1  # Increment x

7.2 Docstrings

Use docstrings to document modules, classes, functions, and methods. Follow the conventions for docstring formatting and content.

def my_function(arg1, arg2):
    """
    This function performs a specific task.

    Args:
        arg1 (int): The first argument, an integer.
        arg2 (str): The second argument, a string.

    Returns:
        bool: True if the operation was successful, False otherwise.
    """
    pass

8. Error Handling

8.1 Exception Handling

Use try/except blocks to handle exceptions gracefully.

try:
    result = x / y
except ZeroDivisionError:
    print("Error: Division by zero.")
except Exception as e:
    print(f"An error occurred: {str(e)}")

8.2 Raising Exceptions

Raise exceptions when appropriate, with clear and descriptive error messages.

def divide_numbers(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero.")
    return a / b

9. Code Organization and Structure

9.1 Module Structure

Organize module code with the following structure:

  1. Module docstring

  2. Imports

  3. Constants and global variables

  4. Helper functions

  5. Main class(es)

  6. Main function (if applicable)

"""
This is the module docstring.
It describes the purpose and functionality of the module.
"""

import sys
import os

# Constants and global variables
MAX_RETRIES = 3
TIMEOUT = 60

# Helper functions
def get_current_time():
    pass

# Main class
class MainClass:
    pass

# Main function
def main():
    pass

if __name__ == "__main__":
    main()

9.2 Class Structure

Organize class code with the following structure:

  1. Class docstring

  2. Class attributes

  3. init method

  4. Instance methods

  5. Class methods

  6. Static methods

class MyClass:
    """
    This is the class docstring.
   It describes the purpose and functionality of the class.
   """

   # Class attributes
   class_attribute = 0

   def __init__(self):
       pass

   # Instance methods
   def instance_method(self):
       pass

   # Class methods
   @classmethod
   def class_method(cls):
       pass

   # Static methods
   @staticmethod
   def static_method():
       pass