Python Style Guide

It’s important to have consistent coding style. Quoted from http://google-styleguide.googlecode.com/svn/trunk/pyguide.html:

BE CONSISTENT.

If you’re editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around all their arithmetic operators, you should too. If their comments have little boxes of hash marks around them, make your comments have little boxes of hash marks around them too.

The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you’re saying rather than on how you’re saying it. We present global style rules here so people know the vocabulary, but local style is also important. If code you add to a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Avoid this.

Import

Only import modules, like:

# modules in standard library.
import os
import sys

# modules from third-party.
import numpy as np

# modules in the current project.
import solvcon as sc
from solvcon import boundcond
from solvcon.io import vtkxml

# explicit relative import is OK.
from . import solver
from . import case

Never import multiple modules in one line:

# BAD BAD BAD
import os, sys

Never do implicit relative import:

# BAD for modules in the current project.
import block

Py3k Compatibility

Enable three Py3k features by adding the following line at top of modules:

from __future__ import division, absolute_import, print_function

Indentation

Always use four white spaces for indentation. Never use a tab. Below is an example vim mode line for Python:

# vim: set ff=unix fenc=utf8 ft=python ai et sw=4 ts=4 tw=79:

It’s good to limit a line to 79 characters. Width of everyone’s monitor is different.

File Format

Blank Lines

Major sections are seperated by two blank lines, while lower-level entities use one blank line.

import os
import sys


class Class(object):
    def __init__(self):
        pass

    def method(self):
        pass


class Another(object):
    def __init__(self):
        pass

Naming

Here show some naming rules that help readability. These conventions should be followed as much as possible, so that the code can be self-explanary.

  • Names of frequently used instances should use 3 letters:

  • The following two-character names have specific meaning:

    • nd: node/vertex.

    • fc: face.

    • cl: cell.

  • The following prefices often (but not always) have specific meanings:

    • nxx: number of xx.

    • mxx: maximum number of xx.

  • Names of iterating counters start with i, j, k, e.g., icl denoting a counter of cell.

    • However standalone i, j, and k should NEVER be used to name a variable. Variables must not use only one character.

    • Trivial indexing variables can be named as it, jt, or kt.

For example,

  • clnnd means number of nodes belonging to a cell.

  • FCMND means maximum number of nodes for a face.

  • icl means the first-level (iterating) index of cell.

  • jfc means the second-level (iterating) index of face.

  • Some special iterators used in code, such as:

    • clfcs[icl,ifl]: get the ifl-th face in icl-th cell.

    • fcnds[ifc,inf]: get the inf-th fact in ifc-th face.

Other than the above specific rules, here is a table for other stuff:

General Naming Convention

Type

Public

Internal

Packages

lower_with_under

Modules

lower_with_under

_lower_with_under

Classes

CapWords

_CapWords

Exceptions

CapWords

Functions

lower_with_under()

_lower_with_under()

Global/Class Constants

CAPS_WITH_UNDER

_CAPS_WITH_UNDER

Global/Class Variablesi

lower_with_under

_lower_with_under

Instance Variables

lower_with_under

_lower_with_under (protected) or __lower_with_under (private)

Method Names

lower_with_under()

_lower_with_under() (protected) or __lower_with_under() (private)

Function/Method Parameters

lower_with_under

Local Variables

lower_with_under

It’s good to name functions or methods as verb_objective(), such that code can look like:

# function.
make_some_action(from_this, with_that)
# method.
some_object.do_something(with_some_information)