Python
Most of our code is written in Python, so this document will concentrate on it.
PEP 8: Official Python Style Guide
Fortunately, with PEP 8 there's an official Style Guide for Python Code. All new Python code you submit should conform to it, unless you have good reasons to deviate from it, for instance readability.
Keep It Simple
The code you write now probably needs to be touched by someone else down the road, and that someone else might be less experienced than you, or have a terrible headache and be under pressure of time. So while a particular construct may be a clever way of doing something, a simple way of doing the same thing can be and often is preferrable.
New-style classes
Python 2 and earlier knows two types of classes, old-style which have no base class, and new-style which have object
as the base class. Because their behavior is slightly different in some places, and some things can't be done with old-style classes, we want to stick to new-style classes wherever possible.
The syntactical difference is that new-style classes have to explicitly be derived from object
or another new-style class.
# old-style classes class OldFoo: pass class OldBar(OldFoo): pass # new-style classes class NewFoo(object): pass class NewBar(NewFoo): pass
Python 3 only knows new-style classes and the requirement to derive from object
was dropped. In projects that will only ever run on Python 3, it's acceptable not to explicitly derive classes without parents from object
, but if in doubt, do it just the same.
Idiomatic code
In Python, it's easy to inadvertently emulate idiomatic styles of other languages like C/C++ or Java. In cases where there are constructs "native" to the language, it's preferrable to use them.
Here are some examples:
Looping
Languages like C normally use incremented indices to loop over arrays:
float pixels[NUMBER_OF_PIXELS] = [...]; for (int i = 0; i < NUMBER_OF_PIXELS; i++) { do_something_with_a_pixel(pixels[i]); }
Implementing the loop like this would give away that you've programmed in C or a similar language before:
pixels = [...] for i in range(len(pixels)): do_something_with_a_pixel(pixels[i])
Here's the "native" way to implement the above loop:
pixels = [...] for p in pixels: do_something_with_a_pixel(p)
It yields pairs of count and the current value like this:
pixels = [...] for i, p in enumerate(pixels): print("Working on pixel no. {}".format(i + 1)) do_something_with_a_pixel(p)
Properties rather than explicit accessor methods
In order to allow future changes in how object attributes (member variables) are set, some languages encourage always using getter and/or setter methods. This is unnecessary in Python, as you can intercept attribute access by wrapping it into a property.
TBD