Integrated style recommendations from my (Barry's) mimelib/Mailman

style guide.  Only added recommendations that Guido agrees with. :)
This commit is contained in:
Barry Warsaw 2002-05-24 16:22:16 +00:00
parent 7112960b46
commit d5a7731ccf
1 changed files with 152 additions and 14 deletions

View File

@ -17,20 +17,23 @@ Introduction
guidelines for the C code in the C implementation of Python[1].
This document was adapted from Guido's original Python Style
Guide essay[2]. This PEP inherits that essay's incompleteness.
Guide essay[2], with some additions from Barry's style guide[5].
Where there's conflict, Guido's style rules for the purposes of
this PEP. This PEP may still be incomplete (in fact, it may never
be finished <wink>).
A Foolish Consistency is the Hobgoblin of Little Minds
A style guide is about consistency. Consistency with this style
A style guide is about consistency. Consistency with this style
guide is important. Consistency within a project is more
important. Consistency within one module or function is most
important.
But most importantly: know when to be inconsistent -- sometimes
the style guide just doesn't apply. When in doubt, use your best
judgement. Look at other examples and decide what looks best. And
don't hesitate to ask!
the style guide just doesn't apply. When in doubt, use your best
judgement. Look at other examples and decide what looks best.
And don't hesitate to ask!
Two good reasons to break a particular rule:
@ -64,8 +67,9 @@ Code lay-out
these warnings become errors. These options are highly
recommended!
For new projects, spaces are strongly recommended over tabs. Most
editors have features that make this easy to do.
For new projects, spaces-only are strongly recommended over tabs.
Most editors have features that make this easy to do. (In Emacs,
make sure indent-tabs-mode is nil).
Maximum Line Length
@ -74,7 +78,7 @@ Code lay-out
possible to have several windows side-by-side. The default
wrapping on such devices looks ugly. Therefore, please limit all
lines to a maximum of 79 characters (Emacs wraps lines that are
exactly 80 characters long.) For flowing long blocks of text
exactly 80 characters long). For flowing long blocks of text
(docstrings or comments), limiting the length to 72 characters is
recommended.
@ -121,6 +125,46 @@ Code lay-out
pages of related sections of your file.
Imports
- Imports should usually be on separate lines, e.g.:
No: import sys, os
Yes: import sys
import os
it's okay to say this though:
from types import StringType, ListType
- Imports are always put at the top of the file, just after any
module comments and docstrings, and before module globals and
constants. Imports should be grouped, with the order being
1. standard library imports
2. related major package imports (i.e. all email package imports next)
3. application specific imports
You should put a blank line between each group of imports.
- Relative imports for intra-package imports are highly
discouraged. Always use the absolute package path for all
imports.
- When importing a class from a class-containing module, it's usually
okay to spell this
from MyClass import MyClass
from foo.bar.YourClass import YourClass
If this spelling causes local name clashes, then spell them
import MyClass
import foo.bar.YourClass
and use "MyClass.MyClass" and "foo.bar.YourClass.YourClass"
Whitespace in Expressions and Statements
Pet Peeves
@ -190,16 +234,18 @@ Comments
Always make a priority of keeping the comments up-to-date when the
code changes!
If a comment is a phrase or sentence, its first word should be
capitalized, unless it is an identifier that begins with a lower
case letter (never alter the case of identifiers!).
Comments should be complete sentences. If a comment is a phrase
or sentence, its first word should be capitalized, unless it is an
identifier that begins with a lower case letter (never alter the
case of identifiers!).
If a comment is short, the period at the end is best omitted.
Block comments generally consist of one or more paragraphs built
out of complete sentences, and each sentence should end in a
period.
You can use two spaces after a sentence-ending period.
You should use two spaces after a sentence-ending period, since it
makes Emacs wrapping and filling work consistenty.
When writing English, Strunk and White apply.
@ -239,7 +285,24 @@ Comments
Documentation Strings
Conventions for writing good documentation strings
(a.k.a. "docstrings") are immortalized in their own PEP[3].
(a.k.a. "docstrings") are immortalized in PEP 257 [3].
- Write docstrings for all public modules, functions, classes, and
methods. Docstrings are not necessary for non-public methods,
but you should have a comment that describes what the method
does. This comment should appear after the "def" line.
- PEP 257 describes good docstrings conventions. Note that most
importantly, the """ that ends a multiline docstring should be
on a line by itself, e.g.:
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
- For one liner docstrings, it's okay to keep the closing """ on
the same line.
Version Bookkeeping
@ -297,7 +360,7 @@ Naming Conventions
leading X for all its public functions. (In Python, this style is
generally deemed unnecessary because attribute and method names
are prefixed with an object, and function names are prefixed with
a module name.)<
a module name.)
In addition, the following special forms using leading or trailing
underscores are recognized (these can generally be combined with any
@ -367,6 +430,7 @@ Naming Conventions
conditions, it is generally called "error" or "Error". It seems
that built-in (extension) modules use "error" (e.g. os.error),
while Python modules generally use "Error" (e.g. xdrlib.Error).
The trend seems to be toward CapWords exception names.
Function Names
@ -399,6 +463,77 @@ Naming Conventions
that Python contains enough loopholes so that an insistent user
could gain access nevertheless, e.g. via the __dict__ attribute.)
Designing for inheritance
Always decide whether a class's methods and instance variables
should be public or non-public. In general, never make data
variables public unless you're implementing essentially a
record. It's almost always preferrable to give a functional
interface to your class instead (and some Python 2.2
developments will make this much nicer).
Also decide whether your attributes should be private or not.
The difference between private and non-public is that the former
will never be useful for a derived class, while the latter might
be. Yes, you should design your classes with inheritence in
mind!
Private attributes should have two leading underscores, no
trailing underscores.
Non-public attributes should have a single leading underscore,
no trailing underscores.
Public attributes should have no leading or trailing
underscores, unless they conflict with reserved words, in which
case, a single trailing underscore is preferrable to a leading
one, or a corrupted spelling, e.g. class_ rather than klass.
(This last point is a bit controversial; if you prefer klass
over class_ then just be consistent. :).
Optimization and Other Programming Recommendations
- class-based exceptions are always preferred over string-based
exceptions. 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.:
class MessageError(Exception):
"""Base class for errors in the email package."""
- Avoid the use of the string module; instead use string methods.
These are always much faster and share the same API with unicode
strings.
- Avoid slicing strings when checking for prefixes or suffixes.
Use startswith() and endswith() instead, since they are faster,
cleaner and less error prone. E.g.:
No: if foo[:3] == 'bar':
Yes: if foo.startswith('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. E.g.
No: if type(obj) is type(1):
Yes: if isinstance(obj, int):
When checking if an object is a string, keep in mind that it
might be a unicode string too! In Python 2.2, the types module
has the StringTypes type defined for that purpose, e.g.:
from types import StringTypes:
if isinstance(strorunicodeobj, StringTypes):
- For sequences, (strings, lists, tuples), use the fact that empty
sequences are false, so "if not seq" or "if seq" is preferable
to "if len(seq)" or "if not len(seq)".
References
@ -410,6 +545,9 @@ References
[4] http://www.wikipedia.com/wiki/CamelCase
[5] Barry's GNU Mailman/mimelib style guide
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mimelib/mimelib/STYLEGUIDE.txt?rev=1.1&content-type=text/vnd.viewcvs-markup
Copyright