Writing Cleaner Python code
When we write code, we often focus on functionality, but the way we format our code is just as important. Good formatting makes code easier to read, understand, and maintain. This article will improve the quality of your Python code by highlighting some of the key conventions from PEP 8 and the Google Style Guide. While you may already use many of these practices, there’s always something new to learn that can make your code even better. The main sources of this article are PEP8 and Google Style Guide.
PEP8 Key Conventions
Code Layout and Formatting
Indentation: Space over tabs (I know most of you hate it!)
Line Length: Limit lines to 79 characters (72 for docstrings)
Blank Lines:
— Top-level function and class definitions: 2 blank lines before.
— Methods within a class: 1 blank line before.
— End files with a single newline.
Naming convention:
— Variables: snake_case
— Classes: PascalCase
— Constants: All caps SNAKE_CASE
— Modules and packages: short, all-lowercase names; underscores if needed for readability
Spaces:
Spaces after commas, colons, and semicolons: a, b, cNo space before a comma, semicolon, or colon.
Around operators: use a single space on each side (e.g., a = b + c), but not for default arguments (def foo(a=1)).
Imports
Imports must be on each its own line and at the top.
Imports must be grouped by (with a blank line after each group),
1. Standard library imports
2. Related third-party imports
3. Local application imports
Here’s an example of the imports,
"""Module docstring describing what this module does."""
# Standard library imports
import os
import sys
from datetime import datetime, timedelta
# Third‑party imports
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
# Local application imports
import myapp.config
from myapp.utils import helper_functionDocstrings
Include docstrings for all public modules, classes, functions, and methods; private methods can omit docstrings or use comments instead. It might be interesting to know that docstrings serve as runtime metadata and are accessible via .__doc__, so their content should be precise and stable.
Docstrings are enclosed by """and it must start with a one‑line summary, started by a capital letter, and terminated by a period.
Get M.Hossein Rahimi’s stories in your inbox
Join Medium for free to get updates from this writer.
docstrings are officially described in PEP 257, referenced by PEP 8 as below,
Module Docstrings
At the top of .py or __init__.py, include a docstring describing the module or package. Start with a one‑line summary, followed by a blank line, and then optionally list exported classes, functions, and exceptions or usage examples. Example,
"""Utility functions for processing text documents.
Provides:
- clean_text()
- tokenize_text()
- summarize_text()
"""Package Docstrings
Placed in the __init__.py of a package directory.
Should describe the overall package purpose and exported modules/subpackages.
"""MyApp package for data processing.
Submodules:
- `.core` : core runner
- `.io` : file and network I/O
"""Function and Method Docstrings
Must be the first statement inside the def, with no blank lines before or after the docstring block.
Use a one-line summary in imperative mood, ending in a period.
Should describe behavior, inputs, outputs, side effects, and exceptions as needed.
Below is an example of Google‑style Function and Method Docstring:
def compute_area(width, height):
"""Compute the area of a rectangle.
Args:
width (float): Width of the rectangle in units.
height (float): Height of the rectangle in units.
Returns:
float: The computed area.
"""
return width * heightClass Docstrings
Immediately follow the class definition, with no blank line before, but one blank line after.
Provide a summary, optionally list public methods/attributes.
Do not duplicate parent class docstrings; just document subclass-specific behavior.
class Person:
"""Represents a person in the system.
This class encapsulates a user’s basic information and contact details.
Attributes:
name (str): The person’s full name.
age (int, optional): The person’s age in years.
"""
def __init__(self, name, age=None):
"""Initialize a new Person.
Args:
name (str): The person’s name.
age (int, optional): The person’s age in years.
Raises:
ValueError: If `age` is negative.
"""
if age is not None and age < 0:
raise ValueError("Age cannot be negative")
self.name = name
self.age = ageType Hints
While PEP 8 primarily focuses on style, it does provide guidance on using Python’s standard type hint syntax (introduced via PEP 484). Static typing is highly beneficial for code clarity, reducing bugs, and improving tooling.
Use no space before, but one space after a colon when annotating types in function signatures:def greet(name: str) -> str:
When combining an annotation with a default value, include spaces around the =:def greet(name: str = "World") -> str:
Always include spaces around the return-type arrow ->:def greet(name: str) -> str:






