Author: Shailen Tuli
Reviewers: Trevor Johns, Ali Afshar, Wesley Chun
All Dev Platform Python code must comply with Pep8.
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.
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.
- No wildcard (
from x import *) imports. - No relative imports (Pep8 merely discourages these).
- Use
from a import b as cstyle when importing more than one module namedbor ifbhas a really long name.
- Never use mutable objects as default values in function or method definitions.
- Use
*argsfor positional varargs. - Use
**kwargsfor named varargs.
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
forclauses. - Do not use conditionals (except in the simplest of cases).
- Prefer using a loop if a list comprehension or a generator expression gets complicated.
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.
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.
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.
Use only if they do not make the code confusing.
Use with caution. Not permitted in samples, except in truly exceptional cases.
-
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.
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.
In samples, omit rigorous exception handling if it distracts from the central purpose of the sample.
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.