Just as a geographical map needs to be laid out consistently and reliably so that you can use it effectively, software programs need to follow consistent and reliable standards to be read and understood easily by fellow programmers.
Minor details such as ordering your file in an expected way, or separating operators with the usual amount of whitespace, can all help readers of your code feel a little less lost and complete their current programming mission with the minimum of frustration!
Let me guess - PEP 8 has something to say about this too?
Of course! PEP 8 has opinions on everything, even when it’s as mundane and trivial as whether to put whitespace around your “=” signs... In this chapter, you’ll learn the most important aspects of laying out your Python code.
Indentation With Spaces or Tabs?
In Python, you can use either spaces or tabs, but not a mixture. Therefore, it’s recommended to use four spaces so that when developers paste code around it, they don’t get “unexpected indent” errors.
However, if you’re working on a project that already uses tabs, then continue with tabs. It’s not worthwhile to replace all the tabs with spaces for the whole project!
Whitespace: Spot the Difference!
Here are two blocks of Python code that are functionally identical. See how many differences you can find! (There are at least 12, depending on how you count.)
# Good code, conforming to PEP 8.def function(my_list, my_value, foo=40):if (my_value == foo):print("They are equal!")first = my_listthe_second = my_listthe_second += 100print(my_list[:5])
#bad code, not conforming to anythingdef function( my_list,my_value,foo = 40 ):if(my_value==foo):print( "They are equal!" )first = my_list[ 0 ]TheSecond = my_list TheSecond+=100print (my_list[ : 5])
The short version is that if your code looks like the first example, it conforms to PEP 8. If it looks like parts of the second example, then it may look ugly and confusing! 👹
Here are some of the key guidelines regarding whitespace. There are examples of each in the code examples above:
Put a single space around assignment operators (
foo = 2) and logical operators (
foo == 2,
foo > 2, etc.). The only exception is when setting default values such as
Never leave blank spaces just inside parentheses or square brackets; write
( expression )or
[ 0 ].
Don’t leave a gap between a function, such as
print()and its arguments.
Do leave a gap between
ifand any parenthesis. Same applies to
for. This is to be consistent with situations where there are no parentheses. In the example above, the if-statement would be better written as:
if my_value == other_value:.
PEP 8 Guidance on Line Breaks
And if you thought we’d finished with whitespace, you’d be wrong! 😅 PEP 8 also has some guidelines on when to use line breaks.
Should I leave blank lines in my code so it’s not all mushed together?
Yes - but in moderation. In books, blank lines are left between paragraphs, but not between each sentence. The same principle applies to Python code - group together related code (similar to paragraphs) but don’t add blank lines otherwise.
Also, PEP 8 recommends the following:
Before a class definition (i.e., when you write
class MyClass) or function definition (i.e., when you write
def my_function(...):), leave two blank lines.
Before a method definition within a class, leave only one blank line.
Maximum Line Length
Some developers are using a narrow window, and it’s inconvenient to read code when it doesn’t fit on the screen (or wraps to the next line).
For this reason, PEP 8 suggests limiting lines of code to 79 characters.
Recently, developers are more likely to use editors with wider windows, so this rule is maybe stricter than necessary. However, it is still required for developers contributing to the Python standard library.
PEP 8 Guidance on Multiline Expressions
If I limit the length of my lines - as recommended - sometimes my expressions are too long and don’t fit on the line! What should I do then?
Use multiple lines for the expression! But you have to be a little careful!
In the following example, it’s difficult to see that
parameter_number_3 is an argument because it appears on the second line, indented the same as the code:
def function_with_a_rather_long_name(parameter_number_1, parameter_number_2,parameter_number_3):my_function(parameter_number_1)return parameter_number_2
PEP 8 recommends the following alternatives to avoid that:
# Wrap the parameters so that they are aligned verticallydef function_with_a_rather_long_name(parameter_number_1, parameter_number_2,parameter_number_3):my_function(parameter_number_1)return parameter_number_2
# Same but only one parameter on each linedef function_with_a_rather_long_name(parameter_number_1,parameter_number_2,parameter_number_3):my_function(parameter_number_1)return parameter_number_2
# Indenting one level (4 spaces) more than the actual body of the functiondef function_with_a_rather_long_name(parameter_number_1,parameter_number_2,parameter_number_3):my_function(parameter_number_1)return parameter_number_2
Notice that in each case, it’s clear at a glance which code is the function arguments and which code is the function’s body. Problem solved!
PEP 8 Guidance on File Layout
Whether you’re looking at a map while lost in the wilderness, or a Python module while lost in thought, it helps if you know where to find things on the page.
So naturally, PEP 8 has a recommended ordering for your Python files!
Comments that refer to the whole file go at the top.
Imports in the following order:
Standard library modules, e.g.,
Third-party library modules, e.g.,
Local modules, e.g.,
MY_CONSTANT_VALUE = 77.
All other code.
To make Python code consistent and easy to read, PEP has various recommendations for code layout.
Code should be indented with four spaces (not tabs).
Code should use appropriate blank spaces and line breaks for padding without bloating the code.
Lines of code should be no longer than 79 characters, and care is needed when breaking long expressions onto multiple lines.
Files should be written with file-level comments first, then imports, constants, then all other code.
So that pretty much covers how to write readable Python code! In the next chapter, we’ll go further and follow advice from PEP 8 on how to write bug-repellent code!