PEP 8
Python evolves and gains new capabilities thanks to its large international community, following rules and standards known as PEP. PEP stands for Python Enhancement Proposal, which are suggestions for Python’s development. These standards allow for unified project documentation for new approved features of the Python language. The most well-known PEP is number eight. PEP 8 contains principles for writing beautiful and concise Python code.
Under each subsection title, you’ll find one of the 19 principles of the Zen of Python. Try to “feel” what the author meant. To see the original text by Tim Peters instead of the Russian adaptation, run the following program.
import this
Why was PEP 8 created?
(Readability counts)
PEP 8 exists to improve code readability. But why is this so important? Why is writing readable code a fundamental principle of Python?
As Python’s creator, Guido van Rossum, said: “Code is read much more often than it is written.” You might spend a few minutes or a day writing code for, say, user authentication. Once written, you won’t write it again. But you’ll definitely return to read it repeatedly. This code might be part of a project you’re working on. Each time you return to this file, you’ll need to remember what this code does and why you wrote it that way.
If you’re a beginner Python programmer, it might be difficult to remember what a certain part of the code does after several days. However, if you follow PEP 8 guidelines, you can be sure your code will be in good order. You’ll know you’ve added enough spaces according to the logical blocks of code.
Adhering to PEP 8 is especially important if you’re looking for a job as a Python developer. Clean and readable code demonstrates high professionalism. It tells the employer about your understanding of proper code structuring.
If you’re a more experienced Python programmer, PEP 8 helps you easily collaborate with other programmers on a single task. Well-readable code is critical in this case. People who haven’t seen you before but are familiar with your code will read it, understanding the idea you wanted to convey.
Implicit Naming Agreement
(Explicit is better than implicit)
When writing Python code, you need to come up with names for many things: variables, functions, classes, packages, and so on. Choosing reasonable names will save you time and effort in the future. From the name, one should understand what a particular variable, function, or class represents. Avoid using incorrect names that can lead to critical errors that are difficult to debug.
Do not use single letters l, O, or I as names due to the risk of confusing them with 1 and 0, depending on the font.
O = 2 # This may look like you want to equate 2 to zero.
Naming Styles
The table below describes some common naming styles in Python code and indicates when to use them:
| Type | Naming Convention | Examples |
|---|---|---|
| Functions | Use lowercase words or words. Separate words with underscores for readability. | function, my_function |
| Variables | Use a single lowercase letter, word, or words. Separate words with underscores. | x, var, my_variable |
| Classes | Start each word with a capital letter. Do not separate words with underscores. | Model, MyClass |
| Methods | Use lowercase words or words. Separate words with underscores for readability. | class_method, method |
| Constants | Use a single uppercase letter, word, or words. Separate words with underscores. | CONSTANT, MY_CONSTANT |
| Modules | Use short lowercase words or words. Separate words with underscores for readability. | module.py, my_module.py |
| Packages | Use short lowercase words or words. Do not separate words with underscores. | package, mypackage |
In addition to choosing the right naming styles, carefully choose the names themselves. Below are some tips on how to do this effectively.
Choosing the Right Name
Choosing names for variables, functions, classes, etc., can be unexpectedly challenging. Carefully consider your choice of names, as this will make your code more readable. The best way to name your objects in Python is to use descriptive names so that it is clear what the object represents.
When naming variables, you might be tempted to choose simple, single-letter lowercase names like x. But if you’re not using x as an argument to a mathematical function, it is unclear what this x represents. Imagine you’re storing a person’s name as a string and want to use string slicing to reformat their name.
You might end up with something like this:
# Not recommended
x = 'Ivan Petrov'
y, z = x.split()
This will work, but you’ll need to keep track of what x, y, and z represent. It can also confuse co-authors. A better choice of names would be something like this:
# Recommended
name = 'Ivan Petrov'
first_name, last_name = name.split()
Similarly, to reduce the number of letters you type, you might be tempted to use abbreviations when choosing names. In the example below, a function db was defined, which takes a single argument x and doubles it:
# Not recommended
def db(x):
return x * 2
At first glance, this might seem like an obvious choice—it’s a great abbreviation for double! But imagine returning to this code in a few days. You’ll likely forget what you meant by this function and might think it’s an abbreviation for database.
The next example is even clearer:
# Recommended
def multiply_by_two(x):
return x * 2
The same philosophy applies to all other data types and objects in Python. Always try to use the most concise and clear names.
Code Layout
(Beautiful is better than ugly)
How you arrange your code plays a huge role in improving its readability. In this section, you’ll learn how to add vertical spaces to enhance the perception of your code. You’ll also learn how to properly use the 79-character line limit recommended in PEP 8.
Monolithic code can be difficult to perceive. Similarly, too many blank lines in the code make it very sparse, forcing the reader to scroll through it more often than necessary. Below are three main rules for using vertical spaces.
Surround top-level functions and classes with two blank lines. Top-level functions and classes should be self-contained and handle separate functions. It makes sense to place additional vertical space around them to make it clear that they are separate:
class MyFirstClass:
pass
class MySecondClass:
pass
def top_level_function():
return None
Separate method definitions within classes with a single blank line. Inside a class, all functions are related to each other. It is recommended to leave only one line between them:
class MyClass:
def first_method(self):
return None
def second_method(self):
return None
Use blank lines within functions to clearly show steps. Sometimes a complex function needs to perform several steps before the return statement. To help the reader understand the logic within the function, it can be helpful to leave a blank line between each step.
In the example below, there is a function to calculate the variance of a list. This is a two-step task, so it makes sense to separate each step with a blank line. There is also a blank line before the return statement. This helps the reader clearly see what is being returned:
def calculate_variance(number_list):
sum_list = 0
for number in number_list:
sum_list = sum_list + number
mean = sum_list / len(number_list)
sum_squares = 0
for number in number_list:
sum_squares = sum_squares + number**2
mean_squares = sum_squares / len(number_list)
return mean_squares - mean**2
If you use vertical spaces correctly, it can significantly improve the readability of your code and help the reader visually understand what this code does.
Maximum Line Length and Line Breaks
PEP 8 suggests limiting the line length to 79 characters. This is recommended so that you can open multiple files side by side and avoid line wrapping.
Of course, it is not always possible to ensure that all statements are 79 characters long. PEP 8 also describes ways to allow statements to span multiple lines. Python assumes line continuation if the code is enclosed in parentheses, brackets, or braces:
def function(arg_one, arg_two,
arg_three, arg_four):
return arg_one
If line continuation is not possible, you can also use a backslash to break the line:
from mypkg import example1, \
example2, example3
Important: if a line break must occur around binary operators, such as addition or multiplication, it should be placed before the operator.
Indentation
(There should be one—and preferably only one—obvious way to do it)
Indentation or spaces at the beginning of a line are a crucial part of Python syntax. How statements are grouped together in Python is determined by the levels of lines.
x = 2
if x > 6:
print('x is greater than 6')
The indentation before the print statement signals Python to execute it conditionally only if the if statement returns True. The same indentation will show Python which code to execute when a function is called or which code is related to a particular class. There are only two key rules for setting indentation, and they are below:
- Use four consecutive spaces for indentation;
- Prefer spaces over tabs.
Spaces vs. Tabs
You can configure your code editor to insert four spaces when you press the Tab key. It is also important to note that mixing spaces and tabs is prohibited in Python 3. Initially, choose how you will set indentation and stick to that choice. Otherwise, instead of executing the code, you will get an error.
Comments
(If the implementation is hard to explain, it’s a bad idea)
Use comments to document the code as it is written. This is important for your colleagues and your understanding of your code in the future. Here are three important key points to consider when adding comments to your code:
- Use a comment length of no more than 72 characters for documentation;
- Do not use abbreviations, start sentences with a capital letter;
- Remember to update comments when the code changes.
An example of a simple comment:
name = 'John Smith' # Student Name
Spaces in Expressions and Statements
(Sparse is better than dense)
The usefulness of spaces in expressions and statements cannot be overstated. If there are not enough spaces, the code can be difficult to read because everything is grouped together. If there are too many spaces, it can be difficult to visually group lines of code into logically related blocks.
Surround the following binary operators with a single space on each side:
- Assignment operators (=, +=, -=, etc.)
- Comparisons (==, ≠, >, <, ≥, ≤) and (is, is not, in, not in)
- Logical (and, or, not)
When = is used to assign a value to a function argument, do not surround it with spaces.
Recommendations for the Programmer
(Simple is better than complex)
It should be noted that in Python, you can come up with several ways to perform the same action. Below will be discussed how to eliminate ambiguity while maintaining consistency.
# Not recommended
my_bool = 4 > 3
if my_bool == True:
return '4 is greater than 3'
Using the equivalence operator here is unnecessary; my_bool can only have two values, True or False. Therefore, it is enough to write like this:
# Recommended
if my_bool:
return '4 is greater than 3'
This way of performing the if statement with a logical operator is simpler and requires less code, so PEP 8 recommends it.
When to Ignore PEP 8
Answering this question is quite difficult. If you flawlessly follow all PEP 8 prescriptions, you can confidently guarantee the “cleanliness,” high readability of the code, and the professionalism of the programmer. This will benefit everyone interacting with your code, from colleagues to the end customer of the product. However, some PEP 8 recommendations are inapplicable in the following cases:
- If following PEP 8 would break compatibility with existing software;
- If the code accompanying what you are working on is incompatible with PEP 8;
- If the code needs to remain compatible with outdated versions of Python.
Conclusion
Now you should understand the ways to create high-quality, readable Python code using PEP 8 recommendations. Although they may seem like a prison for the creator’s mind, following them can really “boost” your code, especially when it comes to sharing work on it with co-authors.
If you want to delve deeper into the intricacies of PEP 8, you can refer to the full English documentation or visit the informational resource pep8.org, which contains the same information in a more structured form. In these documents, you will find recommendations not included in this “extract.”