Recommended Python Style Guide and Coding Standards

Python Style Guide and Coding Standards

When a group of developers work together, it can work wonders in terms of team work but it can have its own downside too.

They may have the same outcomes but they may take different paths to achieve the same outcomes. They may use different ways to do virtually the same thing in programming but in their uniquely diverse ways.

This might sound great for diversity but when you are working on a big project, these apparently simple variations can heavily influence the consistency of programming.

Therefore, it is necessary to aim at standardized coding in order to achieve consistency and avoid any confusion later.

Python Style Guide

Python is a hugely popular programming language for general-purpose programming.

Python stands out for its core belief in readability. The way it makes use of significant whitespace distinguishes it. It is unique as it provides ways to program on small and large scales.

Python is considered to be a beautiful language but until and unless we can keep the source code also beautiful, it may not turn out to be beautiful. The term “beautiful” stands for the way the code is able to do what you wish but it is also easy to read, maintain and debug.

This blog will illustrate what kind of Python coding style should be used along with a list of do’s and don’ts for Python programs.

Identantion

Rule :

  • You need to make use of 4 spaces for indentation

Example :

if True:
    print(“If Works”)

for element in range(0, 5):
    print(element)

list_of_people = [
    "Rama",
    "John",
    "Shiva"
]

dict_of_people_ages = {
    "ram": 25,
    "john": 29,
    "shiva": 26
}
you should use you should avoid
value = square_of_numbers(num1, num2,
                          num3, num4)
value = square_of_numbers(num1, num2,
       num3, num4)
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

Tabs or spaces ?

Rule :

  • Indentation is done using spaces.
  • In order to remain in sync with the code that has been indented with tabs, you should use tabs.
  • Python 3 does not allow combining both- tabs and spaces for indentation. Therefore, you need to select any one and follow it strictly.

Maximum Line Length

Rule :

  • There should be no more than 79 characters in all lines.
  • There should be 72 characters of line length in comments and docstrings.
  • When a literal string won’t fit on a single line, use parentheses for implicit line joining.

Example :

my_string = (‘This is a very long string, so long that it will not fit into just one line ‘ 
    ‘so it must be split across multiple lines.’)
# or
my_string = ‘This is a very long string, so long that it will not fit into just one line ‘ \
    ‘so it must be split across multiple lines.’

Should Break Line before and after a binary operator ?

Rule :

  • It is permissible to break before or after a binary operator, but it is suggested to always break after binary operations and relations.

Example :

total = A
        + B
        + C

hello

you should use you should avoid
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)

Blank Lines

Rule :

  • Two blank lines should be used to separate top-level function and classes.
  • One blank line should be used to separate method definitions inside classes.
  • Sometimes, you can use extra blank lines to separate groups of related functions.

Example :

class SwapTestSuite(unittest.TestCase):
    """
        Swap Operation Test Case
    """
    def setUp(self):
        self.a = 1
        self.b = 2

    def test_swap_operations(self):
        instance = Swap(self.a,self.b)
        value1, value2 =instance.get_swap_values()
        self.assertEqual(self.a, value2)
        self.assertEqual(self.b, value1)

class OddOrEvenTestSuite(unittest.TestCase):
    """
        This is the Odd or Even Test case Suite
    """
    def setUp(self):
        self.value1 = 1
        self.value2 = 2

    def test_odd_even_operations(self):
        instance1 = OddOrEven(self.value1)
        instance2 = OddOrEven(self.value2)
        message1 = instance1.get_odd_or_even()
        message2 = instance2.get_odd_or_even()
        self.assertEqual(message1, 'Odd')
        self.assertEqual(message2, 'Even')

The classes SwapTestSuite and OddOrEvenTestSuite are separated by two blank lines, whereas the method definitions, such as .setUp() and .test_swap_operations() only have one blank line to separate them.

Shebang line

Rule :

  • Use Shebang line to start the main file of a program. The reason why it is useful is because Shebang line enables you to identify the program executable that will run the script.

Example :

#!/usr/bin/python3

Source File Encoding

Rule :

  • For Python source code encoding, you should make use of a special comment at the top of the file to declare the encoding.
  • You should place a magic comment, to define a source code encoding, into the source files either as first or second line in the file, as follows :
    # coding=<encoding name>

Example :

#!/usr/bin/python3
# -*- coding: UTF-8 -*-

Module Level dunder names

Rule :

  • You should make use of module level “dunders” (i.e. names with two leading and two trailing underscores) such as __all__, __author__, __version__, etc. after the module docstring but before any import statements except from __future__imports.

Example :

"""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

Imports

Rule :

  • You should use Imports on separate lines.
  • You should always put Imports at the top of the file, just after any module comments and docstrings, and before module globals and constants.
  • You should put together Imports in the following order:
    1. Standard library imports.
    2. Related third party imports.
    3. Local application/library specific imports.

Make sure that you put a blank line between each group of imports.

  • You should make use of Absolute type of imports when you need to use absolute path of the function or class in import.

Example :

import sklearn.linear_model.LogisticRegression 
  • You should use Relative type of import if your project structure is growing, as it will enhance the readability of code.

Example :

from ..bubble_sort import BubbleSort
  • You should avoid Wildcard imports because they make it complicated in terms of which names are present in the namespace, confusing both readers and automated tools.

Example :

from scikit import *
you should use you should avoid
import os
import sys
import os, sys

Parentheses

Rule :

  • Make sure that you don’t make use of Parentheses in return statements or conditional statements unless using parentheses for implied line continuation. Keep it in mind that there is no problem as long as you use them around tuples.

String quotes

Rule :

  • You can enclose strings with the help of single quote or double quote.
  • You should make use of triple quotes in order to quote a string of multiple lines.

Example :

a = "double quote string"
b = 'single quote string'

print"""
Usage: thingy [OPTIONS]
    h                     Display this usage message
    H hostname               Hostname to connect to
"""

White Space in Expressions and Statements

Rule :

  • You should not use whitespace inside parentheses, brackets or braces.
  • You should also avoid whitespace before a comma, semicolon, or colon. But you should use whitespace after a comma, semicolon, or colon except at the end of the line.
  • You should not use whitespace before the open paren/bracket that begins an argument list, indexing or slicing.
  • You should surround binary operators with a single space on either side for assignment (=), comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not), and Booleans (and, or, not). Make sure you exercise your discretion for the insertion of spaces around arithmetic operators but always remain consistent about whitespace on either side of a binary operator.
  • Make sure you avoid spaces around the ‘=’ sign when they are used to suggest a keyword argument or a default parameter value.
  • You should not use spaces to vertically align tokens on consecutive lines, since it becomes a maintenance burden (applies to :, #, =, etc.).
you should use you should avoid
spam(ham[1], {eggs: 2}, [])
spam( ham[ 1 ], { eggs: 2 }, [ ] )
if x == 4:
    print x, y
x, y = y, x
if x == 4 :
    print x , y
x , y = y , x
dict['key'] = list[index]
dict ['key'] = list [index]
x < 1
x<1
def complex(real, imag=0.0): return magic(r=real, i=imag)
def complex(real, imag = 0.0): return magic(r = real, i = imag)
x = 1
y = 2
long_variable = 3
x                  = 1
y                  = 2
long_variable = 3
FILES = [
    'setup.cfg',
    'tox.ini',
    ]
initialize(FILES,
           error=True,
           )
FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]

When to use trailing commas

Rule :

  • It is not mandatory to use trailing commas. They are mandatory when making a tuple of one element.
  • For better clarity, you should surround the latter in (technically redundant) parentheses.
you should use you should avoid
FILES = ('setup.cfg',)
FILES = 'setup.cfg',

To do style

Rule :

  • Make sure that you use TODO comments for code that is temporary, a short-term solution, or good enough but not perfect.
  • When you use TODOs, they should entail the string TODO in all caps, followed by the name, e-mail address, or other identifier of the person who can best provide context about the problem referenced by the TODO, in parentheses.

Example :

# TODO(kl@gmail.com): Use a "*" here for string repetition.
# TODO(Zeke) Change this to use relations.

Comments

Rule :

  • You should always ensure that comments are kept up-to-date when the code changes!
  • Make sure that comments are complete sentences.
  • Use caps in the first word, unless it is an identifier that starts with a lowercase letter. You should never change the case of identifiers!
  • You should take due care that inline comments are separated by at least two spaces from the statement. They should start with a # and a single space.
    Example :

    x = x + 1                 # Increment x
  • When it comes to block comments, you should ensure that each line starts with the hash mark and a single space. In case you have to make use of more than one paragraph, you should separate them by a line that contains a single hash mark.
    Example :
    # The main function will parse arguments via the parser variable.  These
    # arguments will be defined by the user on the console.  This will pass
    # the word argument the user wants to parse along with the filename the
    # user wants to use, and also provide help text if the user does not 
    # correctly pass the arguments.
    
  • You should write docstrings for all public modules, functions, classes, and methods. It is not mandatory to use Docstrings for non-public methods but you should have a comment that mentions what the method does. You should ensure that this comment appears after the def line.
    Example :

    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

Rule :

  • There are different naming styles in vogue. It helps if one can recognize what naming style is used, independent from what they are used for.

Here’re some general guidelines on how to name your identifiers:

Identifier Convention
Variable Names lower_with_underscores
Constants UPPER_WITH_UNDERSCORES
Function Names lower_with_underscores
Function Parameters lower_with_underscores
Class Names CapitalWords
Method Names lower_with_underscores
Method Parameters and Variables lower_with_underscores
Package & Module lowercase

The below infographic is a very handy resource to every python developer.

Python-Style-Guide