Python style guide
Jump to navigation
Jump to search
This style guide descends from the Python documentation and work done at Mosuki, Devsuki, and Sycle.
For anything not covered in this document, follow PEP 8, PEP 257, and Idioms and Anti-Idioms in Python.
Encoding
- All files should be written using the UTF-8 encoding; set your editor accordingly.
- All files should have the encoding specified at the very top of the file (underneath the #! line if it exists):
# encoding: utf-8
Arrangement
Modules should be arranged like:
- imports
- configuration variables
- functions
- classes
Imports should be arranged so that "import X" is followed by "from X import Y" in blocks ordered by:
- standard library
- external packages
- local packages
- current package
Methods should be arranged like:
__init__- other
__double_underscored__methods that override Python built-in functionality _protectedmethods- public methods
Empty lines
- Two empty lines separate top level functions and classes.
- One empty lines separate methods.
- One empty line may separate conceptually different chunks of code in the same namespace, like control flow blocks (if/elif/else/try/except/for/while/finally/with).
Identifiers
- no abbrs. (abbreviations)
- It's ok to use a clear abbreviation for an identifier that would otherwise collide with a Python keyword or builtin:
bufforbuffer,clsforclass, etc.
- It's ok to use a clear abbreviation for an identifier that would otherwise collide with a Python keyword or builtin:
- NA (no acronyms)
- no wordsruntogether
- no STuDLyCaPS
- no CamelCase, mixedCase, mixed_Case, or Title_Case
- CapitalizeEachWord in class names only
- Do not use negated or negative terminology
- use
send_claim=Trueinstead ofdo_not_send_claim=False - use
escape_output=Trueinstead ofdisable_output_escaping=False
- use
- Avoid plurals when a singular, or similar singulars, are used in the same or similar objects, classes, modules, scopes, or contexts.
- Try to find a good word that describes an entire collection, and fall back to plurals if you can't.
- Examples:
teaminstead ofplayers,staffinstead ofemployees,whitelistinstead ofallowed_items,storyinstead ofparagraphs,menuinstead ofentrees
- Examples:
- Don't use
int,stror other scalar type names as sub-parts of identifiers. - separate words with '_' always
- be as descriptive as possible in identifiers
- the length of an identifier should be inversely proportional to its scope:
- class attributes, methods, and values passed between functions should be descriptive and as long as necessary
- short identifiers are only ok inside functions and methods
- extremely short identifiers are only ok as throwaway variables, iteration indexes, etc.
- long identifiers are ok and almost always good. If your text editor cannot autocomplete long identifiers for you, get a new text editor. Optimize for comprehension, not keystrokes.
- try to stick to the same identifiers for the same things
- use the same identifiers in function/method arguments in their definition and where they are called
- use the same identifiers for similar/overridden method's names and scopes in derived classes
- &c.
- function, method, and executable names should be verb-like
- object, variable, attribute and property names should be noun-like:
- GOOD:
foo_bar = foo_to_bar(foo, bar) - BAD:
foo_to_bar = foo_bar(foo, bar)
- GOOD:
String literals
- Use single quotes around keys and values that are symbol-like, from a fixed or constrained set
- Use double quotes around free-form text
- Ok to use the other kind of quote when you need to include a quote in a string
Comments
- Comment out an unused line of code with a single
# - Comment out English explanations with
#(octothorp followed by a space) to distinguish English from Python - A comment on the same line as code should have two spaces preceding the
# - Don't be shy about deleting unused code rather than commenting it out. Version control is for remembering old code. Comments are not for remembering old code.
Labels
Comment labels make it easy to ack or grep for known issues. There's also a TextMate bundle for them called "TODO".
- Label known problems to fix with
# BUG:followed by an explanation - Label known deficiencies to implement with
# TODO:followed by an exaplanation - Hacks should always be avoided (this is technical debt) but sometimes happen. Label your sin with
# HACK:orBUG: HACK:followed by an explanation of the Right Way to do things.
A less well defined tag we use is # NOTE: . These typically indicate comments of an important nature: pitfalls, important details, etc.
Example
import os
import sys
from functools import partial
import spam
from mypackage.othermodule import OtherObject
def be_fruitful_and(a, b, do_what='multiply'):
"""Fruitly go and be."""
if do_what == 'multiply':
print "multiplying %d and %d" % (a, b)
return a*b
elif do_what == 'divide':
# Man, this sure is fun
print "dividing %d and %d because it's fun" % (a, b)
return a*b
# BUG: need to support addition and subtraction
else:
#raise Exception("Sorry, I don't know how to %s" % do_what)
print "Sorry, I don't know how to %s" % do_what
class Foo(spam):
"""Provide a Foo interface for frobbing spam."""
def __init__(self):
"""Initialize stuff."""
y = 7
x = 12
self.x_times_y = be_fruitful_and(x, y)
def bar(self):
"""Barify the foo."""
z = self.x_times_y
self.x_times_y = 0
return z
class Bar(Foo):
"""Extend :class:`Foo` with tasty Barness."""
def bar(self):
"""Barify the bar.
Barification of the bar allows for further frobbing of Fooified spam.
"""
z = Foo.bar(self)
return z + 1
def something_else(self, another_value):
"""Do that other thing."""
yet_another_value = another_value % self.x_times_y
return be_fruitful_and(another_value, self.x_times_y)