PEP 8 modernisation

Thanks to Guido van Rossum, Barry Warsaw, Raymond Hettinger,
Terry Reedy, Thomas Wouters and others for the constructive
feedback :)
This commit is contained in:
Nick Coghlan 2013-08-01 22:25:37 +10:00
parent 2ea8f1200a
commit 7dba60ceea
1 changed files with 198 additions and 59 deletions

View File

@ -3,12 +3,13 @@ Title: Style Guide for Python Code
Version: $Revision$
Last-Modified: $Date$
Author: Guido van Rossum <guido@python.org>,
Barry Warsaw <barry@python.org>
Barry Warsaw <barry@python.org>,
Nick Coghlan <ncoghlan@gmail.com>
Status: Active
Type: Process
Content-Type: text/x-rst
Created: 05-Jul-2001
Post-History: 05-Jul-2001
Post-History: 05-Jul-2001, 01-Aug-2013
Introduction
@ -23,6 +24,10 @@ This document and PEP 257 (Docstring Conventions) were adapted from
Guido's original Python Style Guide essay, with some additions from
Barry's style guide [2]_.
This style guide evolves over time as additional conventions are
identified and past conventions are rendered obsolete by changes in
the language itself.
A Foolish Consistency is the Hobgoblin of Little Minds
======================================================
@ -41,15 +46,24 @@ style guide just doesn't apply. When in doubt, use your best
judgment. Look at other examples and decide what looks best. And
don't hesitate to ask!
Two good reasons to break a particular rule:
In particular: do not break backwards compatibility just to comply with
this PEP!
1. When applying the rule would make the code less readable, even for
someone who is used to reading code that follows the rules.
Some other good reasons to ignore a particular guideline:
1. When applying the guideline would make the code less readable, even
for someone who is used to reading code that follows this PEP.
2. To be consistent with surrounding code that also breaks it (maybe
for historic reasons) -- although this is also an opportunity to
clean up someone else's mess (in true XP style).
3. Because the code in question predates the introduction of the
guideline and there is no other reason to be modifying that code.
4. When the code needs to remain compatible with older versions of
Python that don't support the feature recommended by the style guide.
Code lay-out
============
@ -59,9 +73,6 @@ Indentation
Use 4 spaces per indentation level.
For really old code that you don't want to mess up, you can continue
to use 8-space tabs.
Continuation lines should align wrapped elements either vertically
using Python's implicit line joining inside parentheses, brackets and
braces, or using a hanging indent. When using a hanging indent the
@ -129,31 +140,41 @@ starts the multi-line construct, as in::
Tabs or Spaces?
---------------
Never mix tabs and spaces.
Spaces are the preferred indentation method.
The most popular way of indenting Python is with spaces only. The
second-most popular way is with tabs only. Code indented with a
mixture of tabs and spaces should be converted to using spaces
exclusively. When invoking the Python command line interpreter with
Tabs should be used solely to remain consistent with code that is
already indented with tabs.
Python 3 disallows mixing the use of tabs and spaces for indentation.
Python 2 code indented with a mixture of tabs and spaces should be
converted to using spaces exclusively.
When invoking the Python 2 command line interpreter with
the ``-t`` option, it issues warnings about code that illegally mixes
tabs and spaces. When using ``-tt`` these warnings become errors.
These options are highly recommended!
For new projects, spaces-only are strongly recommended over tabs.
Most editors have features that make this easy to do.
Maximum Line Length
-------------------
Limit all lines to a maximum of 79 characters.
Aim to limit all lines to a maximum of 79 characters, but up to 99
characters is acceptable when it improves readability.
There are still many devices around that are limited to 80 character
lines; plus, limiting windows to 80 characters makes it possible to
have several windows side-by-side. The default wrapping on such
devices disrupts the visual structure of the code, making it more
difficult to understand. Therefore, please limit all lines to a
maximum of 79 characters. For flowing long blocks of text (docstrings
or comments), limiting the length to 72 characters is recommended.
For flowing long blocks of text with fewer structural restrictions
(docstrings or comments), limiting the line length to 72 characters
is recommended.
Limiting the required editor window width makes it possible to have
several files open side-by-side, and works well when using code
review tools that present the two versions in adjacent columns.
The default wrapping in most tools disrupts the visual structure of the
code, making it more difficult to understand. The limits are chosen to
avoid wrapping in editors with the window width set to 80 (or 100), even
if the tool places a marker glyph in the final column when wrapping
lines. Some web based tools may not offer dynamic line wrapping at all.
The preferred way of wrapping long lines is by using Python's implied
line continuation inside parentheses, brackets and braces. Long lines
@ -214,15 +235,17 @@ control-L as a form feed and will show another glyph in its place.
Encodings (PEP 263)
-------------------
Code in the core Python distribution should always use the ASCII or
Latin-1 encoding (a.k.a. ISO-8859-1). For Python 3.0 and beyond,
UTF-8 is preferred over Latin-1, see PEP 3120.
Code in the core Python distribution should always use UTF-8 (or ASCII
in Python 2).
Files using ASCII should not have a coding cookie. Latin-1 (or UTF-8)
should only be used when a comment or docstring needs to mention an
author name that requires Latin-1; otherwise, using ``\x``, ``\u`` or
``\U`` escapes is the preferred way to include non-ASCII data in
string literals.
Files using ASCII (in Python 2) or UTF-8 (in Python 3) should not have a
coding cookie.
In the standard library, non-default encodings should be used only for
test purposes or when a comment or docstring needs to mention an author
name that that contains non-ASCII characters; otherwise, using ``\x``,
``\u``, ``\U``, or ``\N`` escapes is the preferred way to include
non-ASCII data in string literals.
For Python 3.0 and beyond, the following policy is prescribed for the
standard library (see PEP 3131): All identifiers in the Python
@ -266,11 +289,27 @@ Imports
Put any relevant ``__all__`` specification after the imports.
- Relative imports for intra-package imports are highly discouraged.
Always use the absolute package path for all imports. Even now that
PEP 328 is fully implemented in Python 2.5, its style of explicit
relative imports is actively discouraged; absolute imports are more
portable and usually more readable.
- Absolute imports are recommended, as they are usually more readable
and tend to be better behaved (or at least give better error
messages) if the import system is incorrectly configured (such as
when a directory inside a package ends up on ``sys.path``)::
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
However, explicit relative imports are an acceptable alternative to
absolute imports, especially when dealing with complex package layouts
where using absolute imports would be unecessarily verbose::
from . import sibling
from .sibling import example
Standard library code should avoid complex package layouts and always
use absolute imports.
Implicit relative imports should *never* be used and have been removed
in Python 3.
- When importing a class from a class-containing module, it's usually
okay to spell this::
@ -285,6 +324,18 @@ Imports
and use "myclass.MyClass" and "foo.bar.yourclass.YourClass".
- Wildcard imports (``from <module> import *``) should be avoided, as
they make it unclear which names are present in the namespace,
confusing both readers and many automated tools. There is one
defensible use case for a wildcard import, which is to republish an
internal interface as part of a public API (for example, overwriting
a pure Python implementation of an interface with the definitions
from an optional accelerator module and exactly which definitions
will be overwritten isn't known in advance).
When republishing names this way, the guidelines below regarding
public and internal interfaces still apply.
Whitespace in Expressions and Statements
========================================
@ -760,6 +811,36 @@ With this in mind, here are the Pythonic guidelines:
advanced callers.
Public and internal interfaces
------------------------------
Any backwards compatibility guarantees apply only to public interfaces.
Accordingly, it is important that users be able to clearly distinguish
between public and internal interfaces.
Documented interfaces are considered public, unless the documentation
explicitly declares them to be provisional or internal interfaces exempt
from the usual backwards compatibility guarantees. All undocumented
interfaces should be assumed to be internal.
To better support introspection, modules should explicitly declare the
names in their public API using the ``__all__`` attribute. Setting
``__all__`` to an empty list indicates that the module has no public API.
Even with ``__all__`` set appropriately, internal interfaces (packages,
modules, classes, functions, attributes or other names) should still be
prefixed with a single leading underscore.
An interface is also considered internal if any containing namespace
(package, module or class) is considered internal.
Imported names should always be considered an implementation detail.
Other modules must not rely on indirect access to such imported names
unless they are an explicitly documented part of the containing module's
API, such as ``os.path`` or a package's ``__init__`` module that exposes
functionality from submodules.
Programming Recommendations
===========================
@ -769,10 +850,12 @@ Programming Recommendations
For example, do not rely on CPython's efficient implementation of
in-place string concatenation for statements in the form ``a += b``
or ``a = a + b``. Those statements run more slowly in Jython. In
performance sensitive parts of the library, the ``''.join()`` form
should be used instead. This will ensure that concatenation occurs
in linear time across various implementations.
or ``a = a + b``. This optimization is fragile even in CPython (it
only works for some types) and isn't present at all in implementations
that don't use refcounting. In performance sensitive parts of the
library, the ``''.join()`` form should be used instead. This will
ensure that concatenation occurs in linear time across various
implementations.
- Comparisons to singletons like None should always be done with
``is`` or ``is not``, never the equality operators.
@ -799,29 +882,59 @@ Programming Recommendations
operator. However, it is best to implement all six operations so
that confusion doesn't arise in other contexts.
- Use class-based exceptions.
- Always use a def statement instead of assigning a lambda expression
to a name.
String exceptions in new code are forbidden, and this language
feature has been removed in Python 2.6.
Yes::
Modules or packages should define their own domain-specific base
exception class, which should be subclassed from the built-in
Exception class. Always include a class docstring. E.g.::
def f(x): return 2*x
class MessageError(Exception):
"""Base class for errors in the email package."""
No::
f = lambda x: 2*x
The first form means that the name of the resulting function object is
specifically 'f' instead of the generic '<lambda>'. This is more
useful for tracebacks and string representations in general. The use
of the assignment statement eliminates the sole benefit a lambda
expression can offer over an explicit def statement (i.e. that it can
be embedded inside a larger expression)
- Derive exceptions from ``Exception`` rather than ``BaseException``.
Direct inheritance from ``BaseException`` is reserved for exceptions
where catching them is almost always the wrong thing to do.
Design exception hierarchies based on the distinctions that code
*catching* the exceptions is likely to need, rather than the locations
where the exceptions are raised. Aim to answer the question
"What went wrong?" programmatically, rather than only stating that
"A problem occurred" (see PEP 3151 for an example of this lesson being
learned for the builtin exception hierarchy)
Class naming conventions apply here, although you should add the
suffix "Error" to your exception classes, if the exception is an
error. Non-error exceptions need no special suffix.
suffix "Error" to your exception classes if the exception is an
error. Non-error exceptions that are used for non-local flow control
or other forms of signalling need no special suffix.
- When raising an exception, use ``raise ValueError('message')``
- Use exception chaining appropriately. In Python 3, "raise X from Y"
should be used to indicate explicit replacement without losing the
original traceback.
When deliberately replacing an inner exception (using "raise X" in
Python 2 or "raise X from None" in Python 3.3+), ensure that relevant
details are transferred to the new exception (such as preserving the
attribute name when converting KeyError to AttributeError, or
embedding the text of the original exception in the new exception
message).
- When raising an exception in Python 2, use ``raise ValueError('message')``
instead of the older form ``raise ValueError, 'message'``.
The paren-using form is preferred because when the exception
arguments are long or include string formatting, you don't need to
use line continuation characters thanks to the containing
parentheses. The older form is not legal syntax in Python 3.
The latter form is not legal Python 3 syntax.
The paren-using form also means that when the exception arguments are
long or include string formatting, you don't need to use line
continuation characters thanks to the containing parentheses.
- When catching exceptions, mention specific exceptions whenever
possible instead of using a bare ``except:`` clause.
@ -851,6 +964,21 @@ Programming Recommendations
exception propagate upwards with ``raise``. ``try...finally``
can be a better way to handle this case.
- When binding caught exceptions to a name, prefer the explicit name
binding syntax added in Python 2.6::
try:
process_data()
except Exception as exc:
raise DataProcessingFailedError(str(exc))
This is the only syntax supported in Python 3, and avoids the
ambiguity problems associated with the older comma-based syntax.
- When catching operating system errors, prefer the explicit exception
hierarchy introduced in Python 3.3 over introspection of ``errno``
values.
- Additionally, for all try/except clauses, limit the ``try`` clause
to the absolute minimum amount of code necessary. Again, this
avoids masking bugs.
@ -873,6 +1001,10 @@ Programming Recommendations
# Will also catch KeyError raised by handle_value()
return key_not_found(key)
- When a resource is local to a particular section of code, use a
``with`` statement to ensure it is cleaned up promptly and reliably
after use. A try/finally statement is also acceptable.
- Context managers should be invoked through separate functions or methods
whenever they do something other than acquire and release resources.
For example:
@ -907,9 +1039,6 @@ Programming Recommendations
Yes: if foo.startswith('bar'):
No: if foo[:3] == 'bar':
The exception is if your code must work with Python 1.5.2 (but let's
hope not!).
- Object type comparisons should always use isinstance() instead of
comparing types directly. ::
@ -918,11 +1047,15 @@ Programming Recommendations
No: if type(obj) is type(1):
When checking if an object is a string, keep in mind that it might
be a unicode string too! In Python 2.3, str and unicode have a
be a unicode string too! In Python 2, str and unicode have a
common base class, basestring, so you can do::
if isinstance(obj, basestring):
Note that in Python 3, ``unicode`` and ``basestring`` no longer exist
(there is only ``str``) and a bytes object is no longer a kind of
string (it is a sequence of integers instead)
- For sequences, (strings, lists, tuples), use the fact that empty
sequences are false. ::
@ -947,6 +1080,10 @@ Programming Recommendations
annotation style. Instead, the annotations are left for users to
discover and experiment with useful annotation styles.
It is recommended that third party experimants with annotations use an
associated decorator to indicate how the annotation should be
interpreted.
Early core developer attempts to use function annotations revealed
inconsistent, ad-hoc annotation styles. For example:
@ -1004,6 +1141,8 @@ References
.. [3] http://www.wikipedia.com/wiki/CamelCase
.. [4] PEP 8 modernisation, July 2013
http://bugs.python.org/issue18472
Copyright
=========