Style Guide¶
This part of the developer guide contains instructions for coding styles that are adopted for this project.
The style guide that we use for this project is PEP8. This is the standard for Python code and all IDEs, parsers and code formatters understand and work with this standard. PEP8 leaves room for project specific styles. A good style guide that we can follow is the Google Style Guide.
The following sections will give the most used conventions with a few examples of good and bad.
TL;DR¶
Type | Style | Example |
---|---|---|
Classes | CapWords | ProcessManager, ImageViewer, CommandList, Observation, MetaData |
Methods & Functions | lowercase with underscores | get_value, set_mask, create_image |
Variables | lowercase with underscores | key, last_value, model, index, user_info |
Constants | UPPERCASE with underscores | MAX_LINES, BLACK, COMMANDING_PORT |
Modules & packages | lowercase no underscores | dataset, commanding, multiprocessing |
General¶
- Name the class or variable or function with what it is, what it does or what it contains. A variable named
user_list
might look good at first, but what if at some point you want to change the list to a set so it can not contain duplicates. Are you going to rename everything intouser_set
or woulduser_info
be a better name? - Never use dashes in any name, they will raise a
SyntaxError: invalid syntax
. - We introduce a number of relaxations to not break backward compatibility for the sake of a naming convention. As described in A Foolish Consistency is the Hobgoblin of Little Minds: Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is the most important. [...] do not break backwards compatibility just to comply with this PEP!
Classes¶
Always use CamelCase (Python uses CapWords) for class names. When using acronyms, keep them all UPPER case.
- Class names should be nouns, like Observation
- Make sure to name classes distinctively
- Stick to one word for a concept when naming classes, i.e. words like
Manager
orController
orOrganizer
all mean similar things. Choose one word for the concept and stick to it. - If a word is already part of a package or module, don't use the same word in the class name again.
Good names are: Observation
, CalibrationFile
, MetaData
, Message
, ReferenceFrame
, URLParser
.
Methods and Functions¶
A function or a method does something (and should only do one thing, SRP=Single Responsibility Principle), it is an action, so the name should reflect that action.
Always use lowercase words separated with underscores.
Good names are: get_time_in_ms()
, get_commanding_port()
, is_connected()
, parse_time()
, setup_mask()
.
When working with legacy code or code from another project, names may be in camelCase (with the first letter a lower case letter). So we can in this case use also getCommandPort()
or isConnected()
as method and function names.
Variables¶
Use the same naming convention as functions and methods, i.e. lowercase with underscores.
Good names are: key
, value
, user_info
, model
, last_value
Bad names: NSegments
, outNoise
Take care not to use builtins: list
, type
, filter
, lambda
, map
, dict
, ...
Private variables (for classes) start with an underscore: _name
or _total_n_args
.
In the same spirit as method and function names, the variables can also be in camelCase for specific cases.
CONSTANTS¶
Use ALL_UPPER_CASE with underscores for constants. Use constants always within a name space, not globally.
Good names: MAX_LINES
, BLACK
, YELLOW
, ESL_LINK_MODE_DISABLED
Modules and Packages¶
Use simple words for modules, preferably just one word like datasets
or commanding
or storage
or extensions
. If two words are unavoidable, just concatenate them, like multiprocessing
or sampledata
or testdata
. If needed for readability, use an underscore to separate the words, e.g. image_analysis
.
Import Statements¶
- Group and sort import statements
- Never use the form
from <module> import *
- Always use absolute imports in scripts
Be careful that you do not name any modules the same as a module in the Python standard library. This can result in strange effects and may result in an AttributeError
. Suppose you have named a module math
in the egse
directory and it is imported and used further in the code as follows:
from egse import math
# in some expression further down the code you might use
math.exp(a)
This will result in the following runtime error:
File "some_module.py", line 8, in <module>
print(math.exp(a))
AttributeError: module 'egse.math' has no attribute 'exp'
Of course this is an obvious example, but it might be more obscure like e.g. in this GitHub issue: 'module' object has no attribute 'Cmd'.