Naming Convention
PEP 8 provides guidelines for naming variables, functions, classes, & modules in Python. The naming conventions help make the code more readable & understandable.
Let’s see some key points to remember:
1. Use descriptive & meaningful names that reflect the purpose of the variable, function, or class.
2. Use lowercase letters for variable & function names, separating words with underscores (snake_case).
3. Use uppercase letters for constants, separating words with underscores (UPPER_CASE).
4. Use CamelCase for class names, starting with an uppercase letter (MyClass).
5. Use lowercase letters for module names, separating words with underscores (my_module.py).
6. Avoid using single-character names except for temporary variables in shortcode blocks./
7. Use self as the first argument in instance methods & cls as the first argument in class methods.
For example :
# Constant
MAX_VALUE = 100
# Variable
student_name = "Sinki"
# Function
def calculate_average(numbers):
total = sum(numbers)
count = len(numbers)
return total / count
# Class
class StudentRecord:
def __init__(self, name, age):
self.name = name
self.age = age
Examples
Let's look at some examples that show the application of PEP 8 guidelines in Python code.
Example 1: Naming Conventions
# Bad
def Calc_Avg(nums):
tot = sum(nums)
cnt = len(nums)
return tot / cnt
# Good
def calculate_average(numbers):
total = sum(numbers)
count = len(numbers)
return total / count
In the bad example, the function name `Calc_Avg` uses mixed case & abbreviations, making it harder to understand. The variable names `tot` & `cnt` are also not descriptive. In a good example, the function name `calculate_average` is lowercase, separated by underscores, & conveys its purpose. The variable names `total` & `count` are descriptive & meaningful.
Example 2: Code Layout
# Bad
def calculate_sum(a,b):
return a+b
# Good
def calculate_sum(a, b):
return a + b
In the bad example, there are no spaces after the commas in the function parameters & around the `+` operator. This makes the code harder to read. In the good example, spaces are added after the commas & around the `+` operator, improving readability.
Example 3: Comments
# Bad
# This function calculates the product of two numbers
def multiply(x, y):
return x * y
# Good
def multiply(x, y):
"""
Calculates the product of two numbers.
Args:
x (int or float): The first number.
y (int or float): The second number.
Returns:
int or float: The product of x and y.
"""
return x * y
In the bad example, the comment above the function is redundant & doesn't provide additional information. In a good example, a docstring is used to provide a clear description of the function, its parameters, & its return value. This makes the code more self-explanatory & easier to understand.
Name Style
PEP 8 recommends following specific naming styles for different types of identifiers in Python.
Let’s discuss some common naming styles:
1. Lower Case: Use lowercase letters for variable names, function names, & module names. Separate words with underscores if needed.
Examples:
- `variable_name`
- `function_name`
- `module_name.py`
2. Upper Case: Use uppercase letters for constants. Separate words with underscores if needed.
Examples:
- `CONSTANT_NAME`
- `MAX_VALUE`
3. CamelCase: Use CamelCase for class names. Start with an uppercase letter & capitalize the first letter of each word. Do not use underscores.
Examples:
- `ClassName`
- `MyClass`
4. Mixed Case: Avoid using mixed case naming styles, such as `camelCase` or `PascalCase`, as they are not commonly used in Python.
For example
# Variable names
count = 10
student_name = "Rahul"
# Function name
def calculate_average(numbers):
pass
# Constant name
MAX_VALUE = 100
# Class name
class StudentRecord:
pass
Code Layout
PEP 8 provides guidelines for organizing & formatting Python code to enhance readability.
Let’s see some important points to remember about code layout:
1. Indentation: Use 4 spaces per indentation level. Avoid using tabs for indentation.
Example:
def function():
if condition:
# Indented block
pass
else:
# Another indented block
pass
2. Line Length: Limit each line to a maximum of 79 characters. If a line exceeds this limit, you can break it into multiple lines using parentheses, brackets, or braces.
Example:
long_variable_name = some_function_call(argument1, argument2,
argument3, argument4)
3. Blank Lines: Use blank lines to separate logical sections of code. Use two blank lines before function & class definitions, & one blank line before method definitions inside a class.
Example
def function1():
# Function body
pass
def function2():
# Function body
pass
class MyClass:
def method1(self):
# Method body
pass
def method2(self):
# Method body
pass
4. Whitespace: Use whitespace to improve readability. Add spaces around operators & after commas, but avoid excessive whitespace.
Example
x = 1 + 2 * 3
my_list = [1, 2, 3, 4]
5. Imports: Place import statements at the top of the file, after any module comments & docstrings. Group imports in the following order:
- Standard library imports
- Third-party library imports
- Local application imports
Example
import os
import sys
import numpy as np
import pandas as pd
from mypackage import mymodule
Indentation
PEP 8 places a strong emphasis on consistent indentation to improve code readability.
These are the main guidelines for indentation:
1. Use 4 spaces per indentation level. This applies to all blocks of code, including function & class definitions, loops, & conditional statements.
Example:
def my_function():
if condition:
# Indented block
pass
else:
# Another indented block
pass
2. Avoid mixing spaces & tabs for indentation. It is recommended to use spaces consistently throughout your codebase.
3. In case of line continuations, align the continued line vertically with the opening delimiter or use hanging indentation.
Example
# Aligned with opening delimiter
my_list = [
1, 2, 3,
4, 5, 6,
]
# Hanging indentation
my_dict = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
}
4. For function arguments & parameters, you can use vertical alignment or hanging indentation.
Example:
# Vertical alignment
def my_function(param1, param2,
param3, param4):
pass
# Hanging indentation
def my_function(
param1, param2,
param3, param4,
):
pass
5. Avoid excessive indentation that makes the code difficult to read. If your code becomes too deeply nested, consider refactoring it into smaller functions or using loops to simplify the structure.
Note: Consistent indentation helps make your code more visually appealing & easier to understand at a glance. It also prevents potential errors that can arise from inconsistent indentation.
Indentation following Line Break
When a line of code is too long & needs to be broken into multiple lines, PEP 8 provides guidelines for indentation following the line break.
Let’s look at the main points which we need to consider:
1. When breaking a line after an opening parenthesis, bracket, or brace, align the next line with the opening delimiter.
Example:
my_list = [
1, 2, 3,
4, 5, 6,
]
2. When breaking a line before a closing parenthesis, bracket, or brace, align the closing delimiter with the opening statement.
Example
result = some_function(
argument1, argument2, argument3,
argument4, argument5, argument6,
)
3. If the opening & closing delimiters fit on the same line, you can choose to keep them on the same line.
Example:
my_dict = {
'key1': 'value1', 'key2': 'value2',
'key3': 'value3', 'key4': 'value4',
}
4. When breaking a line for a long function call or definition, you can use hanging indentation to improve readability.
Example
# Function call with hanging indentation
result = some_function(
argument1, argument2,
argument3, argument4,
)
# Function definition with hanging indentation
def my_function(
param1, param2,
param3, param4,
):
pass
5. When breaking a line for a long conditional statement, align the continuation line with the start of the condition.
Example
if (condition1 and
condition2 and
condition3):
# Code block
pass
Use docstring
PEP 8 recommends using docstrings to provide documentation for modules, functions, classes, & methods. Docstrings are string literals that appear as the first statement in a module, function, class, or method definition. They provide a brief description of the purpose, parameters, return values, & any other relevant information.
Now, let’s discuss the guidelines for using docstrings:
1. Use triple double-quotes `"""` to define docstrings. They allow docstrings to span multiple lines.
Example
def my_function(param1, param2):
"""
This is a docstring explaining the purpose of the function.
It can span multiple lines.
"""
pass
2. For one-line docstrings, you can keep the opening & closing quotes on the same line.
Example
def my_function(param1, param2):
"""This is a one-line docstring."""
pass
3. For functions & methods, describe the purpose, parameters, return values, & any exceptions raised.
Example:
def my_function(param1, param2):
"""
Calculates the sum of two numbers.
Args:
- param1 (int): The first number.
- param2 (int): The second number.
Returns:
- int: The sum of param1 and param2.
Raises:
ValueError: If either param1 or param2 is not an integer.
"""
pass
4. For classes, provide a summary of the class's purpose & any important attributes or methods.
Example:
class MyClass:
"""
A class representing a person.
Attributes:
- name (str): The name of the person.
- age (int): The age of the person.
Methods:
- greet(): Prints a greeting message.
"""
pass
5. For modules, include a brief overview of the module's purpose & any key classes, functions, or variables.
Example:
"""
This module provides utility functions for file handling.
Functions:
- read_file(filename): Reads the contents of a file.
- write_file(filename, content): Writes content to a file.
"""
Should a Line Break Before or After a Binary Operator?
PEP 8 guides whether to introduce a line break before or after a binary operator when a line needs to be broken due to its length.
The main guidelines are:
1. It is recommended to break the line before the binary operator, aligning the continuation line with the start of the expression.
Example:
# Recommended: Break before the operator
if (condition1
and condition2
and condition3):
# Code block
pass
# Not recommended: Break after the operator
if (condition1 and
condition2 and
condition3):
# Code block
pass
2. However, in some cases, it may be more readable to break the line after the binary operator, especially if the expressions are long or complex.
Example:
# Breaking after the operator for readability
long_variable_name = (
some_long_expression +
another_long_expression +
yet_another_long_expression
)
3. If breaking the line after the binary operator, indent the continuation line by four spaces to distinguish it from the next line of code.
Example:
# Indenting the continuation line
result = (
some_long_expression +
another_long_expression +
yet_another_long_expression
)
next_line_of_code = do_something(result)
4. Be consistent with the chosen style within a codebase or project. If breaking before the binary operator is the prevalent style, stick to that convention throughout the code.
Note: The main goal is to maintain readability and consistency. Choose the style that enhances the clarity of the code and aligns with the existing codebase conventions.
Importing module
PEP 8 provides guidelines for importing modules in Python to ensure clarity and consistency.
These are the key points to remember:
1. Imports should be placed at the top of the file, after any module comments and docstrings, and before any global variables or constants.
Example:
"""Module docstring."""
import os
import sys
GLOBAL_CONSTANT = 42
2. Imports should be grouped in the following order:
- Standard library imports
- Third-party library imports
- Local application/library imports
Example:
import os
import sys
import numpy as np
import pandas as pd
from mypackage import mymodule
3. Within each group, imports should be sorted alphabetically by module name.
Example
import datetime
import os
import sys
4. Avoid using wildcard imports (`from module import *`) as they can make the code less readable and introduce naming conflicts. Instead, import specific names or use the `import module` syntax.
Example
# Avoid wildcard imports
from module import *
# Prefer specific imports
from module import function1, function2
# Or use import module syntax
import module
5. If importing a long module name, you can use the `as` keyword to provide an alias for readability.
Example
import long_module_name as lmn
6. Avoid importing multiple modules on the same line. Each import should be on a separate line.
Example
# Avoid multiple imports on the same line
import os, sys
# Prefer separate lines for each import
import os
import sys
Blank lines
PEP 8 provides recommendations for the use of blank lines to improve code readability and separation of logical sections.
Let’s see the guidelines for using blank lines:
1. Surround top-level function and class definitions with two blank lines.
Example:
def function1():
pass
def function2():
pass
class MyClass:
pass
2. Method definitions inside a class should be surrounded by a single blank line.
Example
class MyClass:
def method1(self):
pass
def method2(self):
pass
3. Use blank lines sparingly inside functions to separate logical sections of code.
Example
def complex_function():
# Perform setup
setup_code()
# Main logic
main_logic()
# Cleanup or finalization
cleanup_code()
4. Use blank lines to separate groups of related imports.
Example
import os
import sys
import numpy as np
import pandas as pd
from mypackage import mymodule
5. Avoid excessive use of blank lines. Two or more consecutive blank lines should be avoided unless they serve a specific purpose, such as separating large sections of code.
Example:
# Avoid excessive blank lines
def function1():
pass
def function2():
pass
6. In general, aim for a balance between separation and compactness. Use blank lines with caution to improve the readability without creating too much vertical space.
Put the Closing Braces
PEP 8 provides recommendations for the placement of closing braces, brackets, and parentheses in Python code.
Let’s see some of the important guidelines:
1. Closing braces/brackets/parentheses should be placed on a line by themselves, aligned with the opening statement.
Example:
# Closing braces on a separate line
if condition:
# Code block
pass
else:
# Code block
pass
# Closing brackets on a separate line
my_list = [
1, 2, 3,
4, 5, 6,
]
# Closing parentheses on a separate line
result = some_function(
argument1, argument2,
argument3, argument4,
)
2. If a closing brace/bracket/parenthesis is followed by a comma (e.g., in a list or function call), it can be placed on the same line as the last item.
Example
# Closing bracket on the same line as the last item
my_list = [1, 2, 3, 4, 5, 6]
# Closing parenthesis on the same line as the last argument
result = some_function(argument1, argument2, argument3, argument4)
3. If a closing brace/bracket/parenthesis is the only content on a line, it can be placed on the same line as the opening statement.
Example
# Closing brace on the same line as the opening statement
if simple_condition: pass
# Closing bracket on the same line as the opening statement
my_list = [1, 2, 3]
# Closing parenthesis on the same line as the opening statement
result = some_function(argument1, argument2)
Comments
PEP 8 provides guidelines for writing comments in Python code to enhance code readability and maintainability.
The important pointers to remember are:
1. Comments should be clear, concise, and explanatory. They should provide meaningful information about the code.
2. Use inline comments sparingly. Inline comments should be separated by at least two spaces from the statement and start with a # and a single space.
Example:
x = x + 1 # Increment x by 1
3. Block comments should be indented to the same level as the code they describe. Each line of a block comment starts with a # and a single space.
Example
def complex_function():
# This function performs a complex operation
# It takes multiple parameters and returns a result
# based on certain conditions.
pass
4. Use docstrings to provide documentation for modules, functions, classes, and methods. Docstrings should be placed immediately after the definition and use triple double-quotes.
Example:
def my_function(param1, param2):
"""
This function does something with param1 and param2.
Args:
param1: The first parameter.
param2: The second parameter.
Returns:
The result of the operation.
"""
pass
5. Use comments to explain complex or non-obvious code. However, aim to write self-explanatory code whenever possible.
Example
# Calculate the factorial of n using recursion
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
6. Avoid redundant or unnecessary comments. The code should be self-explanatory, and comments should provide additional clarification when needed.
Example
# Avoid redundant comments
x = 42 # Assign 42 to x
7. Keep comments up to date with the code. When modifying code, ensure that the corresponding comments are updated accordingly.
Block Comment
PEP 8 provides guidelines for writing block comments in Python code. Block comments are used to provide a more detailed explanation or documentation for a section of code.
Here are the important points:
1. Block comments should be indented to the same level as the code they describe.
2. Each line of a block comment should start with a `#` and a single space.
3. Block comments should be preceded and followed by a blank line to separate them from the surrounding code.
Example
def complex_function(param1, param2):
# This is a block comment explaining the purpose of the function.
# It takes two parameters, param1 and param2, and performs a complex operation.
# The function returns the result of the operation based on certain conditions.
# Step 1: Perform some initialization
initialization_code()
# Step 2: Process the parameters
processing_code(param1, param2)
# Step 3: Compute the result
result = computation_code()
return result
4. Block comments should provide meaningful and descriptive information about the code they accompany.
5. Use block comments sparingly and only when necessary to explain complex or non-obvious code sections. Strive to write self-explanatory code whenever possible.
6. Avoid using block comments to disable code. Instead, use inline comments or version control systems to manage code changes.
Example
# Avoid using block comments to disable code
# def unused_function():
# unused_code()
Inline comments
PEP 8 provides guidelines for writing inline comments in Python code. Inline comments are short comments that appear on the same line as the code they describe.
The important points need to remember regarding Inline comments are:
1. Use inline comments sparingly. They should be used to provide brief explanations or clarifications for individual statements or expressions.
2. Inline comments should be separated by at least two spaces from the statement they describe.
3. Start an inline comment with a `#` and a single space.
Example
x = 42 # Assign the value 42 to the variable x
# Avoid:
x = 42 #Assign the value 42 to the variable x
4. Inline comments should be concise and descriptive, providing meaningful information about the code.
Example
# Good inline comment
total_cost = price * quantity # Calculate the total cost
# Avoid redundant or obvious comments
x = 42 # Set x to 42
5. Use inline comments to explain the reason behind a specific statement or to clarify the purpose of a variable or expression.
Example
# Inline comment explaining the purpose of a statement
timeout = 60 # Set the timeout to 60 seconds for the API request
6. Avoid using inline comments to explain self-explanatory code. The code should be written in a clear and readable manner.
Example
# Avoid unnecessary inline comments
result = a + b # Add a and b
7. Be consistent with the style and formatting of inline comments throughout the codebase.
Avoid Unnecessary Adding Whitespaces
PEP 8 recommends avoiding unnecessary whitespace in certain situations to maintain code readability and consistency.
The main and important guidelines are:
1. Avoid trailing whitespace at the end of lines.
Example:
# Avoid trailing whitespace
x = 42
2. Avoid adding whitespace immediately inside parentheses, brackets, or braces.
Example
# Avoid whitespace inside parentheses
function_call(arg1, arg2)
# Avoid whitespace inside brackets
my_list = [1, 2, 3, 4]
# Avoid whitespace inside braces
my_dict = {'key': 'value'}
3. Avoid adding whitespace before a comma, semicolon, or colon.
Example:
# Avoid whitespace before comma
function_call(arg1, arg2)
# Avoid whitespace before semicolon
x = 1; y = 2
# Avoid whitespace before colon
if x == 1: print("x is 1")
4. Avoid adding whitespace before the open parenthesis that starts the argument list of a function call.
Example:
# Avoid whitespace before open parenthesis
result = function_call(arg1, arg2)
5. Avoid adding whitespace before the open bracket that starts an indexing or slicing operation.
Example
# Avoid whitespace before open bracket
my_list[index]
my_string[start:end]
6. Avoid adding multiple spaces in a row, except for indentation and alignment purposes.
Example
# Avoid multiple spaces in a row
x = 42 # Incorrect
x = 42 # Correct
Programming Recommendation
PEP 8 provides several programming recommendations to write more readable, maintainable, and Pythonic code.
Let’s discuss some important pointers:
1. Use explicit comparisons:
- Prefer `if x is not None` instead of `if x`.
- Prefer `if x == 0` instead of `if not x`.
- Prefer `if len(my_list) == 0` instead of `if not my_list`.
2. Use `is` and `is not` for comparing singletons like `None`, `True`, and `False`.
3. Use `isinstance()` instead of comparing types directly
- Prefer `isinstance(obj, int)` instead of `type(obj) == int`.
4. Use a def statement instead of an assignment statement when binding a lambda expression to an identifier:
- Prefer `def f(x): return x * 2` instead of `f = lambda x: x * 2`.
5. Use `with` statement for resource management, such as file handling or database connections
with open('file.txt', 'r') as file:
data = file.read()
6. Use `enumerate()` instead of manually incrementing a counter when iterating over a sequence:
for index, item in enumerate(my_list):
print(index, item)
7. Use list comprehensions and generator expressions for simple cases instead of loops
squares = [x**2 for x in range(10)]
8. Use `zip()` to iterate over multiple sequences simultaneously:
for item1, item2 in zip(list1, list2):
print(item1, item2)
9. Use `return` statements consistently:
- Either all return statements in a function should return an expression, or none of them should.
10. Use string methods instead of string module functions:
- Prefer `''.startswith('prefix')` instead of `startswith('', 'prefix')`.
Empty sequences are false in if statements
PEP 8 guides how to handle empty sequences in if statements. In Python, empty sequences, such as empty lists, tuples, strings, and dictionaries, are considered falsy values. This means they evaluate to `False` in a boolean context, such as an if statement.
Let’s see how you can use this property in if statements:
1. Checking if a sequence is empty
my_list = []
if not my_list:
print("The list is empty")
In this example, the if statement checks if `my_list` is empty. If it is, the code inside the if block will be executed.
2. Checking if a sequence is not empty:
my_string = "Hello"
if my_string:
print("The string is not empty")
Here, the if statement checks if `my_string` is not empty. If it contains characters, the code inside the if block will be executed.
3. Avoid explicitly comparing with `True` or `False`
my_tuple = ()
if my_tuple == (): # Avoid this
print("The tuple is empty")
if not my_tuple: # Prefer this
print("The tuple is empty")
It is more idiomatic and readable to use the falsy behavior of empty sequences directly in the if statement, rather than explicitly comparing with `True` or `False`.
4. Be cautious when using this behavior with numeric values
count = 0
if count: # This will not execute
print("Count is not zero")
Keep in mind that the number `0` is also considered falsy in Python. If you need to check for a specific numeric value, it's better to use an explicit comparison.
Don't use not is in if statement
PEP 8 recommends avoiding the use of `not is` in if statements for comparing objects. Instead, it suggests using `is not` for better readability and clarity.
For example :
if x is not None:
print("x is not None")
Avoid using `not is` like this:
if not x is None: # Avoid this
print("x is not None")
The reason for this recommendation is that `is not` reads more naturally and is easier to understand. It shows the intention of checking if an object is not equal to another object.
Using `not is` can be confusing and may lead to readability issues, especially when combined with other logical operators. It can make the code harder to comprehend at a glance.
Here's another example:
# Preferred:
if obj is not isinstance(obj, str):
print("obj is not an instance of str")
# Avoid:
if not obj is isinstance(obj, str):
print("obj is not an instance of str")
Frequently Asked Questions
What is the purpose of PEP 8 in Python?
PEP 8 is a style guide for Python code that provides guidelines and best practices to ensure code consistency, readability, and maintainability.
Are PEP 8 guidelines mandatory for Python code?
PEP 8 guidelines are not mandatory but are highly recommended. Following PEP 8 helps maintain a consistent coding style across projects and makes collaboration easier.
Can I use tools to check my code's compliance with PEP 8?
Yes, there are various tools available, such as pylint, flake8, and pycodestyle, that can check your code's compliance with PEP 8 guidelines and provide suggestions for improvement.
Conclusion
This article discussed the key aspects of PEP 8, the style guide for Python code. We learned about the naming conventions, code layout, comments, programming recommendations, and more. Following the PEP 8 guidelines, you can write clean, readable, and maintainable Python code that aligns with the community's best practices. Writing your code as per Pep 8 is always a good habit because it will make your code clean and more readable.
You can also check out our other blogs on Code360.