-
Notifications
You must be signed in to change notification settings - Fork 20
Python Coding Style Guide
This standard needs to be satisfied in order for your code to be merged into master
branch (this standard is checked by flake8
with pep8-naming
plugin)
PEP8 needs to be strictly followed, since it is the most comprehensive and widely accepted style for python community.
- The original document of PEP8: https://www.python.org/dev/peps/pep-0008/.
- A little more readable document: https://pep8.org/
Here is some of the highlights from PEP8:
-
Naming:
- Function (and method) names should be lowercase, with words separated by underscores:
def function_name()
- Local variable should be lowercase, with words separated by underscore:
local_variable = 1
- Constants are written in all capital letters with underscores separating words:
EXAMPLE_CONSTANTS = "constant string"
- Class names should normally use the CapWords convention:
class ExampleClass
- Function (and method) names should be lowercase, with words separated by underscores:
-
Comment:
- Each line of a block comment starts with a
#
and a single space. (do not use"""
or'''
for block comment, they are used for doc string) - Inline comments should be separated by at least two spaces from the statement. They should start with a
#
and a single space.
- Each line of a block comment starts with a
-
max line length should be 79 char.
- Want to see how to warp your long lines? see this: https://www.python.org/dev/peps/pep-0008/#indentation
- Pycharm will help you to indent when you insert a line break in the middle of a line
This standard needs to be satisfied in order for your code to be merged into master
branch
YES 👍:
for index, element in enumerate(my_list):
pass
NO 👎:
for i, e in enumerate(l):
pass
YES 👍:
def example(input_list):
length = len(input_list)
NO 👎:
def example(list): # list is a type name
len = len(list) # len is a function name
YES 👍:
def sort(unsorted_list):
pass
def enable_files(file_ids):
pass
NO 👎:
def sort(l):
pass
def enable_files(ids):
pass
- The
id
attribute should use lowercase with underscore. - The
class
attribute should use lowercase case with hyphen.
YES 👍:
<p id="example_id" class="example-class"/>
NO 👎:
<p id="exampleid" class="exampleClass"/>
Follow standard for PyDocStyle
This standard needs to be satisfied in order for your code to be merged into master
branch
(this standard is checked by flake8
with flake8_docstrings
plugin)
- Code in comments are confusing for reader, because they cannot distinguish comment from unused code
- For old code, we have version control (
git
) we can always find the old code, leave the old code in comment is redundant - For experiment code, you can open an issue. If we decide your idea is really good but not for now, we can always open a new page in wiki
Comment syntax follows the default Pycharm comment syntax.
YES 👍:
def __init__(self, word_list, file_name):
"""Calculate all the information of the given file.
:param word_list: a dictionary map word to word count representing the
word count of particular file
:param file_name: the file name of that file
"""
NO 👎:
def __init__(self, word_list, file_name):
"""
Calculate all the information of the given file.
Args:
word_list: a dictionary map word to word count representing the
word count of particular file
file_name: the file name of that file
Returns:
None
"""
The formal syntax of the doc string should be as follow:
"""One line summary, ends with period; the next line needs to be empty.
Multiline description (optional).
:para para_name1: para description 1 (optional).
:para para_name2: para description 2 (optional).
:return: description of the variable returned (optional).
"""
or
"""One line doc string, ends with period."""
Typically dividing your functions into smaller function will help you to modulize your application.
A good rule of thumb is do not make your function longer than 30 lines. This will make keeping track of what you are doing much more easier.
A good rule of thumb is that you cannot have more than 12 space indenting (no more than 3 indenting structure).
When you have more and more indentations python became less and less readable, and it will be harder and harder to keep your line under 79 chars.
YES 👍:
class ExampleClass:
# create private helper function when your logic is too complicated
function __do_something_for_elem__(element): # first indenting structure
if element.property is True: # second indenting structure
do_lots_of_things() # third indenting structure
function do_something_for_list(input_list): # first indenting structure
for element in input_list: # second indenting structure
__do_something_for_elem__(element) # third indenting structure
NO 👎:
class ExampleClass:
function do_something_for_list(input_list): # first indenting structure
for element in input_list: # second indenting structure
if element.property is True: # third indenting structure
do_lots_of_things() # forth indenting structure, NOOOOOO!
Typically using keyword parameter will make your code easy to understand:
YES 👍:
generate_matrix(use_freq=True,
token_type="by_gram",
token_size=2)
NO 👎:
generate_matrix(True, "by_gram", 2)
There is a few exceptions:
YES 👍:
sin_of_x = sin(x)
NO 👎:
sin_of_x = sin(value=x)
when you are done with your code, pycharm should give you no error or warnings.
NO 👎:
if some_variable is True:
other_variable = False
print(other_variable) # pycharm will give you an warning here
YES 👍:
if some_variable is True:
other_variable = False
else:
other_variable = True
print(other_variable) # pycharm is happy
Hard as this is to believe, in most case you really do not need to mutate your variable.
YES 👍:
def zip_and_shift_to_positive(x_coords, y_coords):
"""
current function zips two list: xs and ys to xy_coord_list
and then shifts the whole graph to make all the coord positive
"""
# zip list
xy_coord_list = zip(x_coords, y_coords)
# shifts the list
x_shift = min(x_coords)
y_shift = min(y_coords)
positive_coord_list = [[x - x_shift, y - y_shift] for x, y in coord_list]
return positive_coord_list
NO 👎:
def zip_and_shift_to_positive(x_coords, y_coords):
x_shift = min(x_coords)
y_shift = min(y_coords)
# should use list comprehension
positive_coord_list = []
for index in range(len(x_coords)):
# very dangerous, since list is pass by refrence,
# editing list in function can easily render unwanted result
x_coords[i] -= x_shift
y_coords[i] -= y_shift
positive_coord_list.append([x_coords[i], y_coords[i]]) # append is much slower than list comprehension
return positive_coord_list
YES 👍:
my_sorted_list = sorted(my_list)
NO 👎:
my_list = sorted(my_list)
when you give your variable a new name, you are giving the variable a more accurate description, therefore makes the code more clear.
Python gives you the freedom to mutate the type of a variable (dynamically typed), but majority of programmer still thinks static typing provides better security to the program.
Also, if you mutate the type of the variable, it is probably not the same thing as before. Therefore you should give the variable a new name.
YES 👍:
json_dict = {'hello': 'lala', 'tata': 'haha'}
json_str = json.dump(json_dict)
NO 👎:
json_dict = {'hello': 'lala', 'tata': 'haha'}
json_dict = json.dump(json_dict)
As you can see, when you do a json.dump
on the dict, it becomes a string.
Therefore a more accurate description of the variable is not json_dict
but json_str
- User's Guide
- Developer's Guide
- Lexos Bootcamp
- Git Basic
- Git on Pycharm
- Python Tutorial
- Python Coding Style Guide
- Back End Developer's Guide
- The Lexos 4 Frontend
- Javascript Library Maintenance
- In the Margins Content Guide
- Lexos Server Deployment Guide
- How to Install scikit-bio on Windows
- Ajax and jQuery
- Wiki Archiving Guide
- Unit Testing Guide
- Repo Administration Guide
- Proposals