Python’s mix of syntactic and semantic rules make it a powerful computing language. But the code can be written in many ways to instruct computers to perform a given task. Coding standards make Python programs as efficient and effective as possible.
Coding standards help developers standardize their approach. The goal is code that is readable, maintainable and accessible to other humans and computers. Development teams typically have more than one programmer, and readability ensures all developers use code in expected ways. Standardized coding heightens communication between developers and gives the codebase scalability and maintainability benefits.
PEP 8 provides Python-specific coding standards for new programmers and those already fully immersed in the language. Get started with PEP 8 by learning its guidelines for naming conventions, indentation and comments. Then, improve your Python code more with tips for consistency in quotes, spaces, tabs, characters and other formatting choices. Finally, plan how to get the whole development team engaged with code standards.
What is PEP 8?
PEP stands for Python Enhancement Proposal, which is a style guide document about Python coding guidelines and best practices. PEP 0 was written in 2001 by Guido Van Rossum, Barry Warsaw and Alyssa Coghlan. PEP numbers are assigned by the PEP editors, and over time, new PEPs have come out with recommended Python style and design standards, through the current version 8. PEP 8’s purpose is to ensure code consistency, quality and readability.
PEP 8 builds consistency within code structure and design. Consistency is an issue for projects overall, as well as for single code modules and functions. The more consistency in the code, the more readable it is to others. The more readable a codebase, the easier it is for other developers to maintain.
Basic Python formatting standards
PEP 8 indicates several common standards within Python. Standards also have exceptions, so exercise creativity when needed. To start following Python coding best practices, focus on naming conventions, indentation and comments.
Naming conventions
Python’s library of naming conventions applies to code architecture parts and pieces to which developers assign names. Write all new modules and package names according to the following standards to create consistency and readability:
- Follow an overriding principle for all names. Create names based on usage, rather than what function the code performs. Use descriptive names.
- Common naming convention options in Python include the following:
- A single lowercase letter or a single uppercase letter in the name. For example, use p or P.
- All the text in lowercase. For example, write class file as classfile.
- Snake case, wherein all text is in lowercase with words separated by an underscore. An example is class_file_open.
- All the text in uppercase. In this example, class file becomes CLASSFILE.
- A variation on snake case where the text is uppercase with words separated by an underscore: CLASS_FILE_OPEN.
- CapWords or CamelCase, where the first letter of each word in the name uses uppercase. An example is ClassFileOpen.
- MixedCase, where the name starts with a lowercase letter and the next word in the name starts with an uppercase letter. Write the example name as classFileOpen.
- Each word capitalized and separated with underscores. This combination of CamelCase and snake case looks as follows: Class_File_Open.
- Naming conventions can also use the underscore for formatting consistency. Common approaches include the following:
- A single trailing underscore: single trailing underscore_.
- Double leading underscore: __boo move –.
- Double leading and trailing underscore: __boo move__.
- These formatting conventions can cause confusion in specific instances when the letters resemble the integers for 1 and 0. Avoid these naming characters and formatting if possible:
- Lowercase L (l).
- Uppercase I (as in Ignore).
- Uppercase O (as in Oh).
- All identifiers used in a standard library must be ASCII-compatible.
- The Python guidance on package and module names focuses on short names with lowercase letters, relying on other characters where needed for readability. Underscore use for these names is generally discouraged.
- For class names, use the CamelCase style. Use all lowercase letters separated by underscores, like functions, when the primary use is a callable interface.
- For variable names, formatting best practices dictate short type names in CamelCase. Add _co to declare covariant behavior. Add _contra to declare contravariant behavior.
- Global variables are used within a single module only. The __xxx__ with a double underscore before and after indicates a global variable.
- Function names should either appear in lowercase letters and snake case, if it improves readability, or in the mixedCase style, if necessary to retain backward compatibility.
- Name constants on a module level in all uppercase letters and snake case, with underscores between each word.
- Naming conventions can indicate whether an interface is public or internal. Use __all__ attribute to indicate a private or nonpublic API.
- Design for inheritance when naming in Python.
- Do not use leading underscores.
- If a public name collides with a reserved keyword, then add a single trailing underscore to the name.
- For public data attributes, only name the attribute.
- If a class should be subclassed, name the attributes you don’t want to be subclassed with double leading underscores.
Indentation
Python uses four spaces for each indentation level. For continuation lines, wrap the elements vertically using Python line joining inside parentheses, brackets or braces using a hanging indent. With a hanging indent, don’t use arguments on the first line, and use secondary indentation to distinguish a continuation line.
# Correct:
# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
var_three, var_four)
# Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest.
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
# Hanging indents should add a level.
foo = long_function_name(
var_one, var_two,
var_three, var_four)
(Credit: PEP 8 Style Guide for Python Code)
If the conditional portion of an if statement occupies multiple lines, use a two-character keyword plus a space, and add an opening parenthesis to create a four-space indent.
# No extra indentation.
if (this_is_one_thing and
that_is_another_thing):
do_something()
# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()
# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
and that_is_another_thing):
do_something()
(Credit: PEP 8 Style Guide for Python Code)
Comments
Developers might call comments a necessary evil. Comments are essential to build a codebase that others can understand. Comments must be written in complete sentences. Review your comments to be sure they are clear and understandable. Ask another developer to interpret the comments. Did they understand your meaning correctly? If not, edit the comments.
Comments must be up to date. If you change the code, update the comments to match the current code function. To follow the PEP-8 guide, write Python code comments in English. Choosing one language for comments ensures transferability.
Python supports multiple comment types, depending on the code structure. Use block comments that are indented in the same manner as the code. Add a # followed by a single space to start comment text. Separate paragraphs within a comment using a single #. If helpful, use inline comments. These comments appear on the same line as a code statement. Separate inline comments from the code statement with two spaces. Start the inline comment with a # and a single space.
Other Python standards
Developers writing Python code should review PEP-8 and any updates to stay current. The following is a brief list of popular Python coding standards:
- Avoid any trailing white space.
- Refrain from the backslash character with a space to indicate a new line.
- Surround the following binary operators with a single space on either side: =, <, >, !=, <>, <=, >=, in, not in, is, is not, and or not.
- Use either single quotes or double quotes for strings throughout the codebase. Do not mix and match. For triple-quoted strings, always use double quotes.
- Use two blank lines to surround top-level function and class definitions.
- Use blank lines within functions to separate logical sections.
- Use UTF-8 encoding.
- Use non-ASCII characters only when necessary to indicate place and human names.
- Use only ASCII identifiers in English.
- Spaces are used for indentations, not tabs. Don’t mix them.
- Limit all lines to a 79-character maximum.
How do teams enforce coding standards?
Standards enforcement is a difficult subject and a delicate task. Nonetheless, code readability and consistency are cornerstones of the Python language, and to achieve them, developers must stick to the standards.
Development teams that implement and enforce coding standards are often more productive than those working to individual styles and preferences. Don’t make coding more work than necessary. Consistent, readable code based on established standards saves everyone time and frustration. Additionally, it avoids defects that take hours to detect, troubleshoot and resolve because of individualistic and nonstandard coding practices.
Development teams should establish Python coding standards that work for the organization and the team. Leaders should start with a discussion or series of discussions on the topic of coding standards. Find out where team members disagree. Take the time to create a team coding standard using the Python standards. Developers are more likely to follow decisions that are transparent and take into account their suggestions.
During code reviews and other discussions, listen for inconsistencies or lax adherence to the standard. If you find developers aren’t following the standards, to the detriment of the team’s productivity and cohesiveness, hold a one-on-one discussion immediately. Don’t let the code quality suffer before taking action.
Include the team in all Python coding standards and style guide updates to ensure agreement and transparency.
While code consistency is important, there are times when Python developers choose to break with PEP 8 standards. In some scenarios, style guides and standards complicate rather than help the codebase. PEP 8 encourages developers to go against the Python standards when they make the code less readable, break older code modules or prevent the code from being backward-compatible.
Amy Reichert is a 20-plus-year professional QA tester and a QA lead, specializing in test development, execution and management techniques. Her experience comes from a variety of sources, including ERP systems, architectural design, e-commerce and healthcare software.