Skip to content

Instantly share code, notes, and snippets.

@fernandojunior
Last active July 19, 2021 16:26
Show Gist options
  • Save fernandojunior/169487f4a1061bcf0e00c8fe14ef3b54 to your computer and use it in GitHub Desktop.
Save fernandojunior/169487f4a1061bcf0e00c8fe14ef3b54 to your computer and use it in GitHub Desktop.
pep08 examples

https://www.python.org/dev/peps/pep-0008/#pet-peeves

Indentation

Use 4 spaces per indentation level.

Correct:

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

# Hanging indents should add a level.
foo = long_function_name(
    var_one, var_two,
    var_three, var_four)

Wrong:

# Arguments on first line forbidden when not using vertical alignment.
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# Further indentation required as indentation is not distinguishable.
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

Tabs or Spaces?

Spaces are the preferred indentation method.

Tabs should be used solely to remain consistent with code that is already indented with tabs.

Maximum Line Length

Limit all lines to a maximum of 79 characters.

For flowing long blocks of text with fewer structural restrictions (docstrings or comments), the line length should be limited to 72 characters.

Limiting the required editor window width makes it possible to have several files open side by side, and works well when using code review tools that present the two versions in adjacent columns.

The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation.

Imports

Imports should usually be on separate lines:

Correct:

import os
import sys
from subprocess import Popen, PIPE

Wrong:

import sys, os

Imports should be grouped in the following order:

  • Standard library imports.
  • Related third party imports.
  • Local application/library specific imports.

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

Absolute imports are recommended, as they are usually more readable and tend to be better behaved if the import system is incorrectly configured:

Correct:

# Standard library imports
import os
import sys
from subprocess import Popen, PIPE

# Related third party imports
import pandas as pd
import numpy as np

# Local application/library specific imports.
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example

Wildcard imports should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.

Correct:

from pycaret import classification
from pycaret import regression

Wrong:

from pycaret.classification import *
from pycaret.regression import *

Module Level Dunder Names

Module level "dunders" (i.e. names with two leading and two trailing underscores) such as all, author, version, etc. should be placed after the module docstring but before any import statements except from future imports. Python mandates that future-imports must appear in the module before any other code except docstrings:

"""This is the example module.

This module does stuff.
"""

from __future__ import barry_as_FLUFL

__all__ = ['a', 'b', 'c']
__version__ = '0.1'
__author__ = 'Cardinal Biggles'

import os
import sys

String Quotes

In Python, single-quoted strings and double-quoted strings are the same. This PEP does not make a recommendation for this. Pick a rule and stick to it. When a string contains single or double quote characters, however, use the other one to avoid backslashes in the string. It improves readability.

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

Correct:

product_list = ["carro", "moto", "etc."]
product_list = ['carro', 'moto', 'etc.']

Wrong:

product_list = ["carro", 'moto', "bike", 'etc.']

Whitespace in Expressions and Statements

Avoid extraneous whitespace in the following situations:

Correct:

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

foo = (0,)

if x == 4:
    print(x, y)
    x, y = y, x

spam(1)

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

def munge(sep: AnyStr = None):

Wrong:

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

bar = (0, )

if x == 4 :
    print (x , y )
    x , y = y , x

spam (1)

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

def munge(input: AnyStr=None):

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!

Inline comments are unnecessary and in fact distracting if they state the obvious. Don't do this:

x = x + 1                 # Increment x

But sometimes, this is useful:

x = x + 1                 # Compensate for border

Documentation Strings

Write docstrings for all public modules, functions, classes, and methods. Docstrings are not necessary for non-public methods, but you should have a comment that describes what the method does. This comment should appear after the def line.

One-line Docstrings:

def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root
    if _kos_root:
        return _kos_root
    ...

Multi-line Docstrings:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    ...

Naming Conventions

Class names should normally use the CapWords convention.

Because exceptions should be classes, the class naming convention applies here. However, you should use the suffix "Error" on your exception names (if the exception actually is an error).

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

Variable names follow the same convention as function names.

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

SAMPLE_RATE = 0.7


class StoreAI:

    def __init__(self):
        pass


def train_model(input_features: pd.DataFrame):
    input_features.sample(frac=SAMPLE_RATE)
    ...

Programming Recommendations

Use is not operator rather than not ... is. While both expressions are functionally identical, the former is more readable and preferred:

Correct:

if foo is not None:

Wrong:

if not foo is None:

Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier:

Correct:

def f(x):
    return 2*x

Wrong:

f = lambda x: 2*x

Be consistent in return statements.

Correct:

def foo(x):
    if x >= 0:
        return math.sqrt(x)
    else:
        return None

def bar(x):
    if x < 0:
        return None
    return math.sqrt(x)

Wrong:

def foo(x):
    if x >= 0:
        return math.sqrt(x)

def bar(x):
    if x < 0:
        return
    return math.sqrt(x)

Object type comparisons should always use isinstance() instead of comparing types directly:

Correct:

if isinstance(obj, int):

Wrong:

if type(obj) is type(1):

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:
if greeting is True:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment