-
Notifications
You must be signed in to change notification settings - Fork 2
VantTec Python Standard
The VantTec Python standard is based on the PEP 8 -- Style Guide for Python Code and the The Hitchhiker’s guide to Python
For recommendations and modifications, please refer to Pedro Sanchez, Roberto Mendivil or Sebastian Martinez
Here you have the collection of the 19 "guiding principles" that you should take into consideration when writing Python Code.
Look at this script for references on how to write good Python code: https://github.com/hblanks/zen-of-python-by-example/blob/master/pep20_by_example.py
- Do not use tab, use four spaces instead per indentation level.
- Continuation lines should align wrapped elements using a hanging indent. When using a hanging indent the following should be considered; there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line.
# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
var_three, var_four)
# Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest.
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
# Hanging indents should add a level.
foo = long_function_name(
var_one, var_two,
var_three, var_four)
-
The closing brace/bracket/parenthesis on multiline constructs may either be like this:
my_list = [ 1, 2, 3, 4 ] or this: my_list = [ 1,2,3,4 ]
Limit all lines to a maximum of 80 characters. If the length of a line is larger than 80 characters, try to use a “space + backslash”. With this, the editor will detect it is a line continuation marker.
with open('/path/to/some/file/you/want/to/read') as file_1, \
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())
However, there could be some exceptions, like when dealing with ROS Topics, paths or similar.
# Yes: easy to match operators with operands
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)
- Surround top-level function and class definitions with two blank lines. (IMPORTANT!)
- Method definitions inside a class are surrounded by a single blank line.
- Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations).
- Use blank lines in functions, sparingly, to indicate logical sections.
At the beginning of every script you should add these lines:
#!/usr/bin/env python
This means that the program loader takes the presence of “#!” as an indication that the file is a script, and tries to execute that script using the interpreter specified by the rest of the first line in the file.
# -*- coding: utf-8 -*-
Code in the core Python distribution should always use UTF-8 (or ASCII in Python 2). Files using ASCII (in Python 2) or UTF-8 (in Python 3) should not have an encoding declaration.
-
Imports should be on separate lines
YES: import os import sys NO: import os, sys It is okay to do this though: from subprocess import Popen, PIPE
-
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
-
Do not use:
from <library> import *
-
Imports should be grouped in the following order
- Standard imports
- Related third party imports
- Local application / library specific imports
- When importing a class from a class
from Class import MyClass
In Python, double-quoted strings and single-quoted strings are the same, however, double quotes will only be used when dealing with paths and topics (ROS).
-
Avoid extraneous whitespace in the following situations:
-
Immediately inside parentheses, brackets or braces.
YES: spam(ham[1], [eggs: 2}) NO: spam( ham[ 1 ], { eggs: 2 } )
-
Between a trailing comma and a following close parenthesis.
YES: foo = (0,) NO: bar = (0, )
-
Immediately before a comma, semicolon or colon:
YES: if x == 4: print x, y; x, y = y, x NO: if x == 4 : print x , y ; x , y = y , x
-
-
Always surround these binary operators with a single space on either side: assignment (=), augmented assignment (+=, -= etc.), comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not), Booleans (and, or, not).
YES: i = i + 1 submitted += 1 x = x*2 -1 hypot2 = x*x + y*y
-
Don't use spaces around the = sign when used to indicate a keyword argument, or when used to indicate a default value for an unannotated function parameter.
YES: def complex(real, imag=0.0): return magic(r=real, i=imag)
With CapWords
class MyClass
With camelCase
autoNav = AutoNav()
(Let's hope that these variables are meant for use inside one module only.) The conventions are about the same as those for functions. Modules that are designed for use via from M import * should use the all mechanism to prevent exporting globals, or use the older convention of prefixing such globals with an underscore (which you might want to do to indicate these globals are "module non-public").
-
For functions, with lowercase_and_underscore
-
For variables,also with lowercase_and_underscore
- Variable names follow the same convention as function names. Never use names such as I (i), l (L), O or o.
-
mixedCase is allowed only in contexts where that's already the prevailing style (e.g. threading.py), to retain backwards compatibility.
- Always use
self
for the first argument to instance methods - Always use
cls
for the first argument to class methods- More info about this here
- Function and method arguments should be named with a _leading_underscore_lowercase_and_more_underscores
Comments at the beginning of files
'''
----------------------------------------------------------------------------------
@file: file.cpp
@date: Thu Dec 26, 2019
@date_modif: Thu Dec 28, 2019
@author: name
@e-mail:
@co-author: (If multiple co-authors, write the name and e-mail of each one)
@e-mail:
@brief:
@version:
----------------------------------------------------------------------------------
'''
Comment before class only if it not descriptive
'''
---------------------------------------------------------
@name:
@brief:
@param: a[in]: describe
b[out]: describe
@return
---------------------------------------------------------
'''
If you use Visual Studio Code as your code editor, you can add a vertical line into your screen, so you can see where your line should end. Just go to File >> Preferences >> Settings >> search for Editor:Rulers and in the json file just paste this:
"editor.rulers": [80]
It is bad practice to have two disjointed statements on the same line of code
cond1 = <Complex comparison>
cond2 = <Complex comparison>
if cond1 and cond2:
# do something
Use the Python list * operator:
four_name = [None] * 4
Because lists are mutable, the * operator (as above) will create a list of N references to the same list, which is not likely what you want. Instead, use a list comprehension:
four_lists = [[] for_in xrange(4)]
A common idiom for creating strings is to use str.join() on an empty string.
letter = ['s', 'p', 'a', 'm']
word = a.join(letter)
Use sets or dictionaries instead of lists in cases where:
-
The collection will contain a large number of items
-
You will be repeatedly searching for items in the collection
-
You do not have duplicate items.
s = set(['s', 'p', 'a', 'm']) l = set(['s', 'p', 'a', 'm']) return 'p' in s #faster set search return 'p' in l