Fundamentals 29 min read

Master Google’s Python Style Guide: Lint, Imports, and Best Practices

This article presents Google’s official Python style guide, explaining why coding standards matter for Python, how to use pylint for linting, recommended import conventions, handling packages, exceptions, globals, nested classes, list comprehensions, generators, lambda functions, default arguments, properties, threading, naming conventions, and proper module entry points, all illustrated with clear examples and code snippets.

21CTO
21CTO
21CTO
Master Google’s Python Style Guide: Lint, Imports, and Best Practices

Introduction: This guide is based on Google’s official Python style guide and aims to help Python developers adopt consistent coding standards.

Google Python Style Guide
Google Python Style Guide

Background

Python is the primary scripting language at Google. This style guide defines coding conventions for Python to improve readability and maintainability, especially important for dynamic languages where ad‑hoc scripts can become hard to maintain.

The guide is not a community standard; developers may adapt it to their own needs.

Lint

Run pylint on your Python code. Pylint finds bugs that static analysis tools for compiled languages catch automatically. It may produce false positives, so suppress warnings when appropriate.

Advantages: catches easy‑to‑miss errors such as misspelled identifiers or use of undefined variables.

Disadvantages: not perfect; to benefit you must write code with pylint in mind, suppress warnings, improve pylint, or ignore it.

Conclusion: Always run pylint, suppress inaccurate warnings, and expose real issues.

Example of suppressing a warning:

dict = 'something awful'  # Bad Idea... pylint: disable=redefined-builtin

Pylint warnings are identified by a numeric code (e.g., C0112) and a symbolic name (e.g., empty-docstring). Use symbolic names when diagnosing new or updated code.

Useful commands:

pylint --list-msgs</code>
<code>pylint --help-msg=C6409

Recommended parameters:

pylint:disable-msg</code>
<code>pylint:disable

To suppress “unused argument” warnings, name unused parameters “_” or prefix with “unused_”. If you cannot rename, add a comment at the function start.

Imports

Import only packages and modules, not individual symbols.

Definition: Import is the mechanism for reusing code across modules.

Advantages: Simple namespace management; x.Obj clearly shows Obj belongs to module x.

Disadvantages: Module name conflicts; long module names can be cumbersome.

Conclusion: Use full package names for imports, e.g.:

# Reference in code with complete name.
import sound.effects.echo

Or import specific symbols:

from sound.effects import echo

Packages

Use full module paths when importing each module.

Advantages: Avoids name collisions and makes package discovery easier.

Disadvantages: Deployment can be harder because you must replicate the package hierarchy.

Conclusion: All new code should import modules using their full package name.

# Reference in code with complete name.
import sound.effects.echo
# Preferred short form.
from sound.effects import echo

Exceptions

Definition: Exceptions allow you to exit normal control flow to handle error conditions.

Advantages: Keeps error handling separate from regular logic and can unwind multiple stack frames.

Disadvantages: Can make control flow confusing; easy to miss error cases when calling libraries.

Conclusion: Follow best practices—raise exceptions with a single argument, define custom exception classes inheriting from Exception (named Error), avoid bare except:, keep try blocks small, use finally for cleanup, and use as for binding the exception object.

raise MyException("Error message")
raise MyException
raise MyException, "Error message"
raise "Error message"
class Error(Exception):
    pass
try:
    raise Error
except Error as error:
    pass

Global Variables

Definition: Variables defined at module level.

Advantages: Occasionally useful.

Disadvantages: Importing a module executes top‑level code, which may unintentionally change behavior.

Conclusion: Avoid globals; use class variables instead, with exceptions for default options, module‑level constants (uppercase), caching values, or when the variable is deliberately internal.

Nested/Local/Internal Classes or Functions

Definition: Classes can be defined inside methods or functions; functions can be defined inside other functions.

Advantages: Allows definition of utilities limited to a specific scope.

Disadvantages: Instances of nested classes cannot be pickled.

Conclusion: Recommended usage.

List Comprehensions

Definition: List comprehensions and generator expressions provide concise, efficient ways to create lists and iterators without map(), filter(), or lambda.

Advantages: Simple comprehensions are clearer; generators are memory‑efficient.

Disadvantages: Complex comprehensions become hard to read.

Conclusion: Use for simple cases; write each component on its own line and avoid multiple for clauses or nested filters.

# Good example
result = []
for x in range(10):
    for y in range(5):
        if x * y > 10:
            result.append((x, y))

# Bad example (hard to read)
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]

Default Iterators and Operators

Definition: Container types like lists and dictionaries define default iteration and membership operators ( in, not in).

Advantages: Simple, efficient, and work uniformly across types.

Disadvantages: You cannot infer the object type from method names (e.g., has_key()).

Conclusion: Prefer default iterators and operators over explicit method calls.

for key in adict:
    ...
if key not in adict:
    ...
for line in afile:
    ...

Generators

Definition: A generator function yields values, returning an iterator that produces values on demand.

Advantages: Simplifies code and reduces memory usage compared to building full lists.

Disadvantages: None.

Conclusion: Encourage use; document yielded values with a “Yields:” section instead of “Returns:”.

Lambda Functions

Definition: Anonymous functions defined in a single expression, often used with map() or filter().

Advantages: Convenient for short callbacks.

Disadvantages: Harder to read and debug; limited to a single expression.

Conclusion: Use for one‑liner functions; for longer logic prefer regular (nested) functions or the operator module (e.g., operator.mul).

Conditional Expressions

Definition: Ternary syntax x = a if cond else b provides a shorter form of an if statement.

Advantages: Concise.

Disadvantages: Can be harder to read when complex.

Conclusion: Suitable for one‑liner cases; otherwise use a full if block.

Default Argument Values

Definition: Function parameters can have default values, e.g., def foo(a, b=0):.

Advantages: Simulates overload behavior; reduces boilerplate for common cases.

Disadvantages: Default values are evaluated only once at module load, so mutable defaults can lead to unexpected sharing.

Conclusion: Use defaults but never use mutable objects as defaults; replace with None and initialize inside the function.

# Good
def foo(a, b=None):
    if b is None:
        b = []

Properties

Definition: @property decorates methods to provide attribute‑style access.

Advantages: Improves readability, allows lazy computation, and maintains a Pythonic interface without breaking existing code.

Disadvantages: Requires careful implementation; may hide side effects.

Conclusion: Prefer properties for simple getters/setters; use read‑only properties with @property.

class Square(object):
    def __init__(self, side):
        self.side = side
    def __get_area(self):
        return self.side ** 2
    def __set_area(self, area):
        self.side = math.sqrt(area)
    area = property(__get_area, __set_area)
    @property
    def perimeter(self):
        return self.side * 4

True/False Evaluation

Python treats empty values ( 0, None, [], {}, "") as false in boolean contexts.

Advantages: Leads to concise, readable conditionals.

Disadvantages: May be surprising to developers from static languages.

Conclusion: Prefer implicit false checks (e.g., if not seq:) but be aware of edge cases such as distinguishing False from None.

Outdated Language Features

Recommendation: Use modern string methods instead of the string module, replace apply() with direct calls, and prefer list comprehensions or loops over filter(), map(), and reduce().

Lexical Scoping

Definition: Nested functions can reference variables from outer scopes but cannot assign to them without nonlocal or global.

Conclusion: Use lexical scoping for cleaner code, but be aware of subtle bugs when inner functions capture loop variables.

def get_adder(summand1):
    def adder(summand2):
        return summand1 + summand2
    return adder

Function and Method Decorators

Definition: Decorators (prefixed with @) transform functions or methods, e.g., @classmethod, @staticmethod, or custom decorators.

Advantages: Reduce boilerplate and enforce invariants.

Disadvantages: Can hide behavior and run at import time, making failures harder to recover.

Conclusion: Use decorators wisely; document them clearly and provide unit tests.

Threads

Advice: Do not rely on the atomicity of built‑in types; use Queue for inter‑thread communication and proper locking primitives from threading.

Powerful Features

Python offers many advanced features (metaclasses, bytecode manipulation, import hacks, reflection, etc.). While powerful, they make code harder to read and maintain; avoid unless absolutely necessary.

Naming Conventions

Use clear, descriptive names. Follow PEP‑8 and Google style: modules and functions in lower_with_underscores, classes in CapWords, constants in ALL_CAPS, private names with a leading underscore, and avoid single‑character names except for loop counters.

Main

Even scripts should be importable without executing main functionality. Guard entry point with:

def main():
    ...
if __name__ == '__main__':
    main()

Avoid top‑level code that performs actions on import.

Comments

Comments should be complete sentences, updated when code changes, and use proper spacing. Block comments start with # and may be separated by a line containing only #. Inline comments require at least two spaces before the #. Write comments in English unless you are certain the code will never be read by non‑Chinese speakers.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

lintbest-practicespython3importsstyle guidecoding-standards
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.