Skip to content

Instantly share code, notes, and snippets.

@shailen
Last active August 29, 2015 14:06
Show Gist options
  • Save shailen/8238ac5e0c156379a0f9 to your computer and use it in GitHub Desktop.
Save shailen/8238ac5e0c156379a0f9 to your computer and use it in GitHub Desktop.

Python Style Guide

Author: Shailen Tuli
Reviewers: Trevor Johns, Ali Afshar, Wesley Chun

Existing guide

All Dev Platform Python code must comply with Pep8.

Tools

Use the pep8 tool to confirm that your code is Pep8 compliant.

Use pylint for code analysis. Running pylint on your code should not generate any errors.

PyLint sometimes reports spurious warnings. You can suppress such warnings using line-level comments (use disabled:<warning-name> syntax). Add explanatory comments if reason for the suppression isn't obvious. Do this only for truly spurious warnings.

Additional guidelines for all Python code

These restrictions are not required by Pep8, but must be followed in your Python code. This includes samples (including snippets added to docs), larger apps, and libraries.

Imports

  • No wildcard (from x import *) imports.
  • No relative imports (Pep8 merely discourages these).
  • Use from a import b as c style when importing more than one module named b or if b has a really long name.

Arguments

  • Never use mutable objects as default values in function or method definitions.
  • Use *args for positional varargs.
  • Use **kwargs for named varargs.

List Comprehensions and generator expressions

Prefer generator expressions to list comprehensions, since they do not require creating a list in memory. Use list comprehensions (and not generator expressions) when you need to use list methods or functions like sorted() or reversed() that require a list as an argument.

Prefer list comprehensions or generator expression over calls to map() and filter().

Follow these rules to improve readability:

  • Do not use multiple for clauses.
  • Do not use conditionals (except in the simplest of cases).
  • Prefer using a loop if a list comprehension or a generator expression gets complicated.

Properties

Use properties for accessing or setting data where you would normally have used simple accessor or setter methods.

Always use the @property decorator in version 2.6 or higher.

Inheritance with properties can be tricky. Use carefully.

True/False evaluations

Use implicit Boolean values whenever possible. Use this:

if not books:
    ...

Avoid this:

if len(books) == 0:
    ...

Since empty sequences are false, use this:

if seq:
    ...

Avoid this:

if len(seq):
    ...

Never use == or != to compare None. Use is or is not.

Distinguish False and True from None. For example:

if x is not None and x:
    ...

Be aware that 0 (number) is False while "0" (string) is True.

Function and Method Decorators

Use 'builtin' decorators like @staticmethod and @classmethod liberally. Use 'user-defined' function and method decorators judiciously.

In sample code, use decorators only when they do not obscure the focus of the sample through hard-to-understand implicit behavior.

Nested/Local/Inner Functions

Use only if they do not make the code confusing.

Nested/Local/Inner Classes

Use with caution. Not permitted in samples, except in truly exceptional cases.

Threading

  • Prefer the higher-level threading module over the lower-level thread module. Prefer using the queue to communicate data between threads.

  • Do not rely on the atomicity of built-in types.

  • Recommended for I/O-bound operations. Not recommended for CPU-bound operations.

Main

Put a script’s main functionality inside main() and check if __name__ == 'main': before executing your main program:

def main():
    ...

if __name__ == '__main__':
    main()

Test your main() code like you would test any other code.

Exceptions

In samples, omit rigorous exception handling if it distracts from the central purpose of the sample.

Context managers and the with statement

Where possible, prefer using the with statement instead of implementing try...except...finally usage blocks.

For example, opening files (with open(filename) as fp: ...) and acquiring locks (with lock: ...).

The with statement was introduced in Python 2.6. When using earlier versions, implement code to perform cleanup (for example, closing a file or releasing a lock) yourself.

Consider writing your own context managers when writing complex code for creating shared resources.

Testing

  • Use the Unittest framework and the unittest.mock library.
  • For simple cases, test functions with naked asserts.
  • You may use Nose for testing.
  • When using a framework, use the testing infrastructure recommended by the framework.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment