PEP8 and
PEP20 (import this) should be considered as the starting points. Unless specified otherwise, we follow the guidelines laid out there. For a brief overview, read the Python Guide’s entry on the subject.
PEP8 exceptions
Indentation. You can use 2 or 4 spaces to indent code. The most important point is not to mix and match in any given project. Never use hard tabs.
Installation
All packages should be installable through pip by running (inside project root):
$ pip install [-e] .This means that the package needs a setup.py file which is used by setuptools during installation. To expose console scripts it’s preferred to use
entry points over explicit Python scripts.
Starting point
To easily get set up with a base project structure we should provide a central skeleton repository to base future Python projects on. We might like to consider something like
Cookiecutter.
Python 2 vs. 3 support
Code should be written to take advantage of straight forward ways to accomplish universal Python support. This means:
- Sticking to pure Python code whenever possible.
- Making liberal use of
from __future__ import <e.g. print_function>on any page where nessesary. This includes but is not limited to:- print_function
- unicode_literals
- absolute_import
- division
- The Python 3 version of the
openfunctions should be used through
from codecs import open. - Use Python 3 style
relative imports: from .subpackage import func
Command line utilities/scripts
If you are building anything remotely complex, the command line framework of choice is
Click. It’s an elegant and flexible package with a great syntax.
Imperative vs. functional programming
Is writing unit tests for your code a piece of cake? If “yes”, then you need not worry - you are probably writing good quality already. However, if you are struggling with your tests it might help to consider more of a functional (rather than imperative) approach. Read an introduction to functional programming or take away some of the key points:
- Each function should do only one thing.
- Write stateless functions that perform tasks without knowledge of what’s going on beyond it’s scope.
- Treat all data structures as immutable.
- Think hard before adding for/while loops, there’s usually a cleaner way to do it.
- Compose small, discrete components into larger once.
Docstrings
Functions, methods and classes should be annotated using
Google Style Docstrings. They look a little something like this:
def find(some_id):
"""Returns a single item defined by it's unique id. Returns
``None`` if it can't find the requested item.
Args:
some_id (str): unique item id
Returns:
dict or None: item from the data store or ``None``
Examples:
>>> find('1')
{'id': 1, 'director': 'P.T. Anderson', ...}
"""
passHelpful tools
We encourage using a
linter to continously check the syntax of your code. The Python community maintains a number of linters such as pep8, and PyFlakes.
Another resource that can greatly ease collaboration is
EditorConfig. It’s an effort to provide a cross editor configuration format and in placed in your project and commited to source control. You also need to install a plugin for your favorite editor, e.g. Sublime.