PEP 8: What Python code should be like

by Alex
PEP 8: What Python code should be like

Python has certain code standards that all programmers try to follow. These standards are described in the PEP8 documentation. Any popular programming language requires different programmers to write approximately the same style of code. Deviation from the standard will not cause errors in program execution, but is considered bad form among professional programmers.

Why is it important to standardize code?

In fact, programmers spend most of their time analyzing code rather than writing it. This is because nothing is written from scratch. They take solutions which are already ready and debugged and modify them to suit a particular project. In addition, it is often necessary to maintain existing programs with hundreds of thousands of lines of code. If every programmer writes code with a different style, it becomes a very difficult task to analyze it. Therefore, it is important that Python developers follow certain conventions that allow standardizing the code, making it more understandable to any specialist. The guidelines for creating beautiful code in Python do not define the style of code completely. Therefore, the programmer can do some things at his own discretion, but he must still follow the guidelines that are defined in the standard. Within the development team, a particular style of coding may evolve which may in some places violate accepted conventions. This situation is not uncommon and acceptable, but the programmer must remember that if he leaves this team, he will have to re-learn how to write code in accordance with accepted standards.

Code Markup in Python

This section contains guidelines for determining how to mark up code in Python 3 (spaces, indents, and lines).

Indentation

Four spaces are used to denote a new nesting level. When separating function arguments on multiple lines, the indentation size may be different. If it is a declaration or function call (no function body), you can either align the following lines to the opening bracket

f1 = func(first_arg, second_arg,
          third_arg, fourth_arg)

or use four spaces, but with obligatory carry of the first line:

f1 = func(
    first_arg, second_arg,
    third_arg, fourth_arg)
It is not mandatory to use 4 spaces to continue an enumeration. You can use another number of spaces, for example, 2.

If any other code follows the list of arguments (for example, if it is a function being declared), then 4 more spaces are added to the indent of the arguments:

def func(
        first_arg, second_arg, 
        third_arg, fourth_arg):
    print(fourth_arg)

This is done to separate the arguments from the body of the function. In the case of the if statement, the programmer may or may not use extra indents:

if(temp > 5 and
        temp < 25):
    some_func(some_args[])
if(temp > 5
    and temp < 25):
    some_func(some_args[])

If you don’t use extra spaces, you can separate the body of the conditional statement with a one-line comment, if you wish. This may improve readability in some code editors due to the highlighting of the comment. A closing construct in a function or structure may be placed below the first character of the bottom line:

names = [
    "John", "Alex",
    "Olivia", "Jacob",
    ]

It can also be placed at the very beginning of a line:

f = some_f(
    "str1", "str2",
    "str3", "str4",
)

The programmer can also use tabs, but spaces are preferable. Furthermore, the use of both tabs and spaces is not only discouraged, but also causes errors at the interpreter.

Maximum line length

The programmer should not use more than 79 characters in one line. Lines of long multi-line text (comments, documentation) are limited to 72 characters.

Thanks to these restrictions programmers can open several files with code on one screen at once, work comfortably on small screens (ultrabooks, netbooks) and easily understand the code. Parentheses are the best way to implement splitting the code into multiple lines. However, programmers can also use the backslash sign ““.

Binary operators and spaces

You must always put spaces around a binary operator, otherwise the readability of the code will be very poor.

Right:

math_rez = a * b - x + y

Incorrect:

math_rez = a * b - x + y

In addition, if operators are used in a multi-line expression, they must always be carried along with the right operand:

max_sum = (first_sum

+ second_sum
+ third_sum)

Blank lines

Definitions of external classes and functions are surrounded by two empty lines (two lines at the top). Methods within a class are separated by one empty line. Groups of functions can be separated by an additional empty line. Groups of related lines of code can be separated by empty lines to make it easier to understand the logic of the program. You cannot use empty lines between an external code block and a nested code block.

Encoding

Python 3 source code files must always be UTF-8 encoded. Previously, Python 2 used ASCII.

If you need to use characters from other encodings, you should use the escape sequences: x, u, U, N.

Import

Each new module must be imported on a new line:

import sys
import time

If you import more than one part of a module you can write them on one line, separated by commas:

from time import sleep, ctime

Module placeholders are always at the beginning of the file, below the documentation lines and above the declaration of constants. The imports must be divided into groups, with a blank line between them:

  1. Standard libraries.
  2. Third-party libraries.
  3. Other modules of the project.

Using “*” when importing is considered bad form. The point is that such imports give no idea of the names that are in the imported namespace, which is not only confusing, but can also lead to errors.

Quotation marks in strings

In Python, you can use both single and double quotes. However, if double quotes are used in a string, the programmer should select the string with single quotes and vice versa. This improves the readability of the string. For strings of documentation is necessarily used three double quotes. This is described in more detail in PEP 257.

Spaces in expressions and operators

When used correctly, spaces increase the readability of code, however, in certain situations you should avoid their use.

  • Inside curly, round or square brackets.

Correct:

mix_arr = ("John", [176, 70], {"age" : 14})

Wrong:

mix_arr = ("John", [ 176, 70 ], { "age" : 14 } )
  • Between a comma and a closing bracket.

Before a comma, period, or colon. In the cut operation, however, a colon must have the same number of spaces on both sides. Correct: mix_arr[0:2] or mix_arr[0 : 2] Wrong: mix_arr[0 :2] or mix_arr[0: 2]

  • Between the function name and the bracket with arguments passed into it.

Correct:

custom_function(args)

Incorrect:

custom_function(args)
  • You cannot use more than one space to align assignment operators of different expressions.

Correct:

weight = 70
height = 1.76
body_mass_index = 22.5

Incorrect:

weight = 70
height = 1.76
body_mass_index = 22.5
  • All assignment and comparison operators must be separated from operands by spaces.
  • If operators with different priorities are used in an expression, and it is necessary to emphasize this, it is allowed to use spaces only around these operators.

Example:

y = 2*x - 1/x
  • If an assignment character is used to specify a default parameter or a named argument, it is not separated by spaces.

Example:

def graph(x=0.0, y=0.0)
  • Do not write multiple instructions on one line (separated by semicolons).

Incorrect:

x = y + 1; y = y + 1; x = y * 1.1
  • If the loop body consists of one short line, you can write it on the same line as the loop.

Example:

while isAlive: increase_hunger()

Use of commas

Commas are usually optional. An exception is the use of commas in a tuple consisting of a single element. In that case, put the contents of the tuple in parentheses. Correct:

names = ("John,")

Works, but not recommended:

names = "John",

The use of commas is especially relevant when working with a version control system, where the list of values or arguments must be constantly expanded. In this case, each new argument is written on a new line. Correct:

names = [
    "John",
    "Olivia",
    ]

Incorrect:

names = ["John", "Olivia",]

Comments

Comments are an important part of any project because they help understand how the code works and what features it has. Programmers use comments not only to make other experts understand the code but also to help them not to forget how and why they have implemented some functions. Comments must reflect the essence of the code and not contradict it. If the code is changed for some reason, the comments should also be changed. All comments should be complete sentences, and if the first word is not an identifier, it should begin with a capital letter.

All comments must be written in English, even if the programmers are not from an English-speaking country and non-English-speaking programmers are currently working on the project.

Comments may be written in languages other than English if you are 120% sure that this code will never be viewed by people who do not speak your language.

Block comments

Block comments are used when it is necessary to explain the actions of a block of code. Usually such comments are placed above the code block on a separate line.

# This code does something very interesting
a = 5
b = 10
a = b - a + a

In-line comments

These are comments that explain the actions of a line of code and are written on the same line as the code. They must be separated from the code by at least two spaces. Such comments are not recommended because in most cases they explain obvious things and are of no practical use.

a = a / 2 # Dividing a number by two

However, in some cases they can be useful when the real purpose of the string is not obvious:

a = a / 2 # Getting the middle of the screen

Documentation strings

All open modules, functions, classes and their components must be documented. This rule does not apply to private methods, but you can write a comment between the “def” line and the body of the method that describes the purpose of the method. See PEP 257 for more on the documentation convention. The quotation marks indicating the end of lines of documentation must be moved to a new line.

"""Speed determination.

Keyword arguments:
distance -- distance traveled in meters
time -- time in seconds (default 1)
"""

However, if the documentation consists of one line, the quotes do not carry over.

"""Some info about something."""

Naming conventions

The naming conventions in Python are imprecise, so there is no list that completely defines the naming style in Python. For all new packages and modules, the current naming standard must be used.

If for some reason a library uses its own naming style that violates the accepted standard, then the programmer must write code in the style that the library uses in order not to break the internal consistency of the code.

Main Principle

If a name is an open part of an application programming interface, it should reflect usage, not implementation.

Name Styles

Names in Python can be chosen according to one of many styles. You can determine which naming style is used regardless of what it is used for. The following styles are commonly used:

  • b (single lowercase letter)
  • B (single capital letter)
  • lowercase
  • lower_case_with_underscores (lowercase with a delimiter stroke)
  • UPPERCASE (uppercase)
  • UPPER_CASE_WITH_UNDERSCORES (upper case with hyphenation)
  • CapitalizedWords (CamelCase) – each new word starts with a capital letter
  • mixedCase (differs from the previous one in that the first letter is lowercase)

Names that are best not to use

Never use lowercase English letters: l (“el”), O (capital “o”), and I (capital “i”). An uppercase “o” is indistinguishable from a zero, and “l” and “I” from each other. If you do need to use l (“el”) replace it with a capital “L”.

Package and Model Names

Modules must have short, lower case names. Lowercase underscores may be used in module names if it improves readability. If a C or C++ module is accompanied by a Python module which provides a higher-level interface, the C/C++ module name begins with a lowercase character (_modulename).

Class Names

Classes are given names according to the CapitalizedWords naming style.

Exception names

Because exceptions are essentially classes, the same naming convention applies to them as to classes. The programmer can add an “Error” suffix to emphasize that the exception is an error.

Global Variable Names

Global variables are named using the same naming convention as functions. In addition, global variables should only be used within a single module.

If the module is supposed to be imported with the command from module import *, you should describe all allowed to import objects in __all__

. This prevents global variables from being imported and also prevents importing objects that, according to their implementation, should not be externally accessible. __all__ is a list of importable objects, i.e. public.

Function and variable names

For function names, we use lower case. If you want to increase readability, you can separate the words with an underscore character. Variable names are chosen according to the same rules as function names. In cases where it is necessary to maintain backward compatibility with the library (e.g., threading.py), it is acceptable to use mixedCase.

Function and Method Argument Names

The first argument is always self for instance methods and cls for class methods. If a function argument has a name that conflicts with a reserved language keyword, you should add an underscore character to the end of it. This is better than abbreviating or changing the name with a loss of meaning.

  • Right: tuple_
  • Incorrect: tpl tupl

Variable and method names of class instances

Same style as for functions: lower case and lower underscores if necessary.

For closed method and instance attributes, use lower case at the beginning of the name (_method).

To avoid naming conflicts with subclasses, you should use two lowercase underscores at the beginning of names. If the Animal class has a __a attribute, a reference like Animal.__a will not work (in this case you can use Animal._Animal__a), because the interpreter will change the name. Double underscores should only be used to avoid naming conflicts in classes and subclasses.

Constants

Constants are defined at plugin level and are written in uppercase with the word separated by underscores. Examples:

  • TOTAL_SUM
  • SUM
  • TOTAL

Programming guidelines

  • The code should be compatible with other Python implementations such as PyPy, IronPython and others.
  • If you want to compare anything with language objects such as None, be sure to use the is or is not operators, not the equal sign. Also, never make a check if x is not None. As this may cause an error if x is a container.
  • The expressions “is not” and “not ... is” are not functionally different. However, for better code readability it is better to use the first expression.
  • Do not assign a lambda-expression to a variable, because the advantage of a lambda-expression is that it can be embedded in long code. Instead, declare a function with def.
  • If you need to catch an exception, specify a specific error. If you just write except, the compiler will catch all exceptions, which is sure to cause problems.

Right:

try:
    import some_module
except ImportError:
    print("Import impossible")

Incorrect:

try:
    import some_module
except:
    print("I didn't set the error type, "
          "you can't use ctrl+c")
  • There must be a minimum of code within the exception catching construct. If this rule is not followed, it may not be obvious what caused the error.
  • To compare the type of two objects, use the special function isinstance(), not the is operator.

Right: isinstance(object, int) Wrong: type(object) is type(99)

  • You cannot compare a variable with a boolean type using equality or is.

Correct:

if isAlive:

Incorrect:

if isAlive == True:

Incorrect:

if isAlive is True:

Related Posts

LEAVE A COMMENT