python code specification
Code format
sentence
import statement
- The import statement should be written in separate lines
# Correct writing import os import sys # Not recommended import sys,os # Correct writing from subprocess import Popen, PIPE
- The import order is as follows: (there should be a blank line division between the import of each module type, and the order of modules in each group should be arranged in ascending order from top to bottom according to the first letter of the module)
- Standard library
- Related third party libraries
- Local library
import os import sys import msgpack import zmq import foo
In code statement
- Usually, each statement should have a single line
However, if the test results and test statements fit on the same line, you can also put them on the same line If it is an IF statement, you can do this only if there is no else In particular, never do this for try/except, because try and except cannot be placed on the same line
# Correct writing if foo: bar(foo) # Wrong writing if foo: bar(foo) else: baz(foo) try: bar(foo) except ValueError: baz(foo) try: bar(foo) except ValueError: baz(foo)
indent
- Indent each level with 4 spaces. (never use tab, nor mix tab with blank space (I don't know why you can't use tab?)
- Use vertical implicit indentation or hanging indentation in parentheses.
EXAMPLE:
# (vertical implicit indent) align the left bracket foo = long_function_name(var_one, var_two, var_three, var_four) # (hanging indentation) generally, only one more indentation is required foo = long_function_name( var_one, var_two, var_three, var_four) # (hanging indentation) but in the following cases, you need to add another layer of indentation to distinguish it from the subsequent statement blocks def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # Right bracket fallback my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', )
Error demonstration:
# When vertical alignment is not used, the first row cannot have parameters. foo = long_function_name(var_one, var_two, var_three, var_four) # The hanging indentation of a parameter cannot be distinguished from the indentation of subsequent code blocks. def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # The right bracket does not fall back and is not recommended my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', )
Line width / Wrap
- No more than 80 characters per line, except:
- Long import module statement
- URL in comment
- You can use backslashes for line breaks, preferably parentheses
# Recommended writing: foo_bar(self, width, height, color='black', design=None, x='foo', emphasis=None, highlight=0) if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong'): # If a text string cannot fit on one line, parentheses can be used to realize implicit line connection x = ('This is a very long, very long, very long ' 'Very long very long very long very long very long very long string') # In the comment, place the long URL on one line if necessary Yes: # See details at #http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html No: # See details at # http://www.example.com/us/developer/documentation/api/content/\ # v2.0/csv_file_name_extension_full_specification.html
Blank line
- Two blank lines are used to split the definition of top-level functions and classes
- A single blank line is used to split the methods in the class definition
EXAMPLE:
# The method definition of a class is divided by a single empty line, and two empty lines divide the definition of the top-level function and class. class A(object): def method1(): pass def method2(): pass def method3(): pass
Trailing comma
Yes: golomb3 = [0, 1, 3] Yes: golomb4 = [ 0, 1, 4, 6, ] No: golomb4 = [ 0, 1, 4, 6 ]
Space
# Don't put spaces before commas, semicolons, colons, but after them (except at the end of the line) Yes: if x == 4: print x, y x, y = y, x No: if x == 4 : print x , y x , y = y , x # Add a space on both sides of the binary operator, such as assignment (=), comparison (=, <, >,! =, < >, < =, > =, in, not in, is, is, not), Boolean (and, or, not) As for how to use the spaces on both sides of the arithmetic operator, you need to make a good judgment However, both sides must be consistent Yes: x == 1 No: x<1 # When '=' is used to indicate keyword parameters or default parameter values, do not use spaces on both sides Yes: def complex(real, imag=0.0): return magic(r=real, i=imag) No: def complex(real, imag = 0.0): return magic(r = real, i = imag) # Do not use spaces to vertically align marks between multiple lines, Because it will become a burden of maintenance(Apply to:, #, = etc.): Yes: foo = 1000 # notes long_name = 2 # Notes do not need to be aligned dictionary = { "foo": 1, "long_name": 2, } No: foo = 1000 # notes long_name = 2 # Notes do not need to be aligned dictionary = { "foo" : 1, "long_name": 2, }
brackets
- Use parentheses rather than abuse. Do not use parentheses in return statements or conditional statements except for row joins However, it is OK to use parentheses around tuples.
Yes: if foo: bar() while x: x = bar() if x and y: bar() if not x: bar() return foo for (x, y) in dict.items(): ... No: if (x): bar() if not(x): bar() return (foo)
Quotation marks
- Natural languages use double quotation marks "...", such as error messages; In many cases, it is still unicode, using u "Hello world"
- The machine identification uses single quotation marks'... ', such as key in dict
- Regular expressions use native double quotes r "..."
- The document description (docstring) uses three double quotes ""... ""
notes
In general, it is better to have wrong comments than no comments. So when a piece of code changes, the first thing is to modify the comments!!!
- Comment blocks comment blocks are usually applied before the code and have the same indentation as the code. Each line starts with '#' and # is followed by a single space.
EXAMPLE:
# Have to define the param `args(List)`, # otherwise will be capture the CLI option when execute `python manage.py server`. # oslo_config: (args if args is not None else sys.argv[1:]) CONF(args=[], default_config_files=[CONFIG_FILE])
- Single line comment, at least 2 spaces away from the code (use as little as possible)
EXAMPLE:
x = x + 1 # Compensate for border
- Documentation Comments
Docstring, as a document, usually appears in the module header, function and class header, so that it can be passed through the object in python__ doc__ Object to get the document. The editor and IDE can also give automatic prompts according to docstring.
EXAMPLE:
# A multiline document with the first line capitalized and the end "" should be in a separate line """Return a foobang Optional plotz says to frobnicate the bizbaz first. """ # A single line document with the ending "" on the same line. """Return a foobang"""
The numpy standard is adopted for the description of function parameters and return values, as shown below
def func(arg1, arg2): """Write a one sentence summary of the function here(as: Calculate average). Here is the specific description. parameter ---------- arg1 : int arg1 Specific description of arg2 : int arg2 Specific description of Return value ------- int Specific description of the return value see -------- otherfunc : Other correlation functions, etc... Example -------- Example use doctest format, stay`>>>`The code can be automatically run by the document test tool as a test case >>> a=[1,2,3] >>> print [x + 3 for x in a] [4, 5, 6] """
- type annotation
EXAMPLE:
Yes: def func(a: int) -> List[int]: def func(a: int = 0) -> int: ... No: def func(a:int=0) -> int: ...
- TODO annotation, using TODO annotation for temporary code, is a short-term solution.
# TODO(kl@gmail.com): Use a "*" here for string repetition. # TODO(Zeke) Change this to use relations. If your TODO yes"Do sth in the future"Form of, Then make sure you include a specified date("2009 Resolved in November")Or a specific event("Wait until all customers can handle it XML Remove these codes upon request").
Naming conventions
-
Package and module name: lower_with_under as short as possible
-
Class name: CapsWords hump
Note: pyqt5 item The ui file is converted to py file, although the class name does not meet the above specifications, do not change it
-
Constant name: CAPS_WITH_UNDER
-
Function name and variable name: lower_with_under
Programming suggestions
Class inheritance
If a class does not inherit from other classes, it explicitly inherits from object The same is true for nested classes
# Inheriting from object is to make properties work properly, and this can protect your code from potential Python incompatibilities This also defines some special methods that implement the default semantics of objects, including__ new__, __init__, __delattr__, __getattribute__, __setattr__, __hash__, __repr__, and __str__ . Yes: class SampleClass(object): pass class OuterClass(object): class InnerClass(object): pass class ChildClass(ParentClass): """Explicitly inherits from another class already.""" No: class SampleClass: pass class OuterClass: class InnerClass: pass
Comparison / judgment
- For comparison of None, use is or is not instead==
- Use is not instead of not... Is, the former is more readable
EXAMPLE:
# Yes if foo is not None # No if not foo is None
- Use Startswitch() and Endswitch() replaces string slicing to check prefix and suffix * * startswitch() * * and endswitch are more concise and help reduce errors
EXAMPLE:
# Yes if foo.startswith('bar'): # No if foo[:3] == 'bar':
- Use isinstance() instead of comparing object types
EXAMPLE:
# Yes if isinstance(obj, int): # No if type(obj) is type(1):
- The bool of an empty sequence (string, list, tuple) type object is False:
# Yes if not seq: pass if seq: pass # No if len(seq): pass if not len(seq): pass
- Do not use = = for bool comparisons
# Yes if greeting: pass # No if greeting == True pass if greeting is True:# Worse pass
Close file
At the end of the file and sockets, explicitly close it
# The "with" statement is recommended to manage files: with open("hello.txt") as hello_file: for line in hello_file: print line # For file like objects that do not support the use of "with" statements, use contextlib closing(): import contextlib with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page: for line in front_page: print line
character string
-
Avoid using the + and + = operators to accumulate strings in loops.
Because strings are immutable, doing so creates unnecessary temporary objects and results in quadratic rather than linear runtime As an alternative, you can add each substring to the list and use it at the end of the loop join connection list (you can also write each substring to a cStringIO.StringIO cache.)
Yes: x = a + b x = '%s, %s!' % (imperative, expletive) x = '{}, {}!'.format(imperative, expletive) x = 'name: %s; score: %d' % (name, n) x = 'name: {}; score: {}'.format(name, n) No: x = '%s%s' % (a, b) # use + in this case x = '{}{}'.format(a, b) # use + in this case x = imperative + ', ' + expletive + '!' x = 'name: ' + name + '; score: ' + str(n) Yes: items = ['<table>'] for last_name, first_name in employee_list: items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name)) items.append('</table>') employee_table = ''.join(items) No: employee_table = '<table>' for last_name, first_name in employee_list: employee_table += '<tr><td>%s, %s</td></tr>' % (last_name, first_name) employee_table += '</table>'
- Keep the consistency of using string quotes in the same file
Yes: Python('Why are you hiding your eyes?') Gollum("I'm scared of lint errors.") Narrator('"Good!" thought a happy Python reviewer.') No: Python("Why are you hiding your eyes?") Gollum('The lint. It burns. It burns us.') Gollum("Always the great lint. Watching. Watching.")
abnormal
- The Exception class should inherit from Exception, not BaseException
- When capturing exceptions, try to specify specific exceptions and try not to use exception exception. What problems should be caught instead of problems
EXAMPLE:
# Yes (catch specific exception) try: import platform_specific_module except ImportError: platform_specific_module = None # No (do not global capture) try: import platform_specific_module except: platform_specific_module = None
- The code in the try/except clause should be as few as possible to avoid shielding other errors
EXAMPLE:
# Yes try: value = collection[key] except KeyError: return key_not_found(key) else: return handle_value(value) # No try: return handle_value(collection[key]) except KeyError: # The handle may be caught_ KeyError in value() instead of collection return key_not_found(key)
Return value
- When a function or method has no return value, it should explicitly return None
# Yes def foo(): return None # No def foo(): return
pycharm code formatting shortcut
Ctrl+Alt+O: optimize import statement
Ctrl+Alt+L: optimize code format (comments, blank lines, spaces, etc.)
reference material
(92 messages) Jupiter notebook writing specification_ treelly's blog - CSDN blog
Python code writing specification - memory writing - blog Garden (cnblogs.com)