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 c
style when importing more than one module namedb
or ifb
has a really long name.
- Never use mutable objects as default values in function or method definitions.
- Use
*args
for positional varargs. - Use
**kwargs
for 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
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.
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.