"Code is read much more often than it is written." — PEP 8
PEP 8 includes a comprehensive list of suggested style guidelines for Python. PEP 20 provides Python's guiding principles.
Following the style guidelines of a programming language improves the readibility of your code.
If a guideline would make the code less readable, do not apply it!
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
Use descriptive names
Choose variable and functions names that clearly indicate their purpose;
Avoid unclear abbreviations unless widely recognized
n
num_students
calc_pop_dens()
calculate_population_density()
Maintain proper code structure
x=5+3
x = 5 + 3
# Increment counter
"Comments that contradict the code are worse than no comments".
Indentation: 4 spaces (never tabs!).
Line Length: Fix a maximum! PEP8 suggests 79 for code and 72 for docstrings.
There are exception: Long import statements; URLs; pathnames.
There are exception:
Avoid explicit line continuation with backslashes (\). Use paratheses (brackets, or braces) for implicit line joining instead:
\
Bad
my_long_string = "my_long_string is a very, very," \ + " very, very long string!"
Good
my_long_string = ("my_long_string is a very, very," " very, very long string!")
if very_long_condition \ and something in whatever: pass
if (something_very_long and something_esle in whatever): pass # Or: if ( something_very_long and something_esle in whatever ): pass
Implicit line joining should allign elements vertically, or use a hanging indent:
long_function_name(var_one, var_two, var_three, var_four)
long_function_name(var_one, var_two, var_three, var_four) # Or: long_function_name( var_one, var_two, var_three, var_four, )
my_list = [1, 2, 3 4, 5, 6]
my_list = [1, 2, 3 4, 5, 6] # Or: my_list = [ 1, 2, 3 4, 5, 6, ]
def long_function_name( var_one, var_two, var_three, var_four): pass
def long_function_name(var_one, var_two, var_three, var_four): pass # Or: def long_function_name( var_one, var_two, var_three, var_four ): pass
Use
as
import os import sys import numpy as np from sklearn.preprocessing import StandardScaler from mypkg.subpkg import MyClass
snake_case
camelCase
PascalCase
ALL_CAPS
alllower
Avoid using Python keywords like if, else, for, class, etc., as variable names.
prefix with underscore: - _private_var private variables - __var to invoke name mangling to avoid naming conflicts in subclasses.
_private_var
__var
...and much more!
PEP8: https://peps.python.org/pep-0008/ Google Python Style Guide: https://google.github.io/styleguide/pyguide.html
pylint
flake8
ruff
black
autopep8
Install ruff:
pip install ruff
To run the linter in the current directory:
ruff check
To resolve automatically the 'fixable' errors:
ruff check --fix
It is always better to use a virtual environment for your project!
Ruff integrates very nicely with git pre-commit
Ruff: https://docs.astral.sh/ruff/