Python Code Style

This article is translated from Google Docs

http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Python_Style_Rules

 

illustrate

The style of this article is Google's internal Python code style.

 

1. Semicolon

If there are multiple lines of code, do not use a semicolon after each line, and do not use a semicolon to put multiple lines of code on one line

 

2. Line length

80

 

3. Parentheses

Use sparingly (meaning not to use or not to use, unless there is a special purpose), for example

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)

 

4. Indent

4 characters

 

5. Blank line

Use two blank lines between the two most successful definitions and one blank line between the different methods

 

6. Space

parentheses, square brackets, no spaces between curly brackets

Yes: spam(ham[1], {eggs: 2}, [])

No:  spam( ham[ 1 ], { eggs: 2 }, [ ] )

 Comma, semicolon, no space before the colon, followed by a space unless 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

parentheses, no space before square brackets

 

Yes: spam(1)

No:  spam (1)

Yes: dict['key'] = list[index]

No:  dict ['key'] = list [index]

 Do not use spaces around the equal sign, when distinguishing parameters and setting default values

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 for extra alignment

Yes:
  foo = 1000  # comment
  long_name = 2  # comment that should not be aligned

  dictionary = {
      'foo': 1,
      'long_name': 2,
  }

No:
  foo       = 1000  # comment
  long_name = 2     # comment that should not be aligned

  dictionary = {
      'foo'      : 1,
      'long_name': 2,
  }

 

7. Shebang Line

Most .py files do not need to start with #!, except for the main file (ie the entry file) which starts with #!/usr/bin/python.

This beginning is used to find the python interpreter for the kernel.

 

8. Notes, documentation

Modules should add a license file

Functions and methods should be annotated unless the following conditions are met

1. Not visible from the outside

2. Very short

3. Obviously

As follows, the annotation template comes from bigtable

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
    """Fetches rows from a Bigtable.

    Retrieves rows pertaining to the given keys from the Table instance
    represented by big_table.  Silly things may happen if
    other_silly_variable is not None.

    Args:
        big_table: An open Bigtable Table instance.
        keys: A sequence of strings representing the key of each table row
            to fetch.
        other_silly_variable: Another optional variable, that has a much
            longer name than the other args, and which does nothing.

    Returns:
        A dict mapping keys to the corresponding table row data
        fetched. Each row is represented as a tuple of strings. For
        example:

        Se 'Serak': ('Rigel VII', 'Preparer'),
         'Zim': ('Irk', 'Invader'),
         'Lrrr': ('Omicron Persei 8', 'Emperor')}

        If a key from the keys argument is missing from the dictionary,
        then that row was not found in the table.

    Raises:
        IOError: An error occurred accessing the bigtable.Table object.
    """
    pass

 class annotation

class SampleClass(object):
    """Summary of class here.

    Longer class information....
    Longer class information....

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    def __init__(self, likes_spam=False):
        """Inits SampleClass with blah."""
        self.likes_spam = likes_spam
        self.eggs = 0

    def public_method(self):
        """Performs operation blah."""

 inner block comment

# We use a weighted dictionary search to find out where i is in
# the array.  We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.

if i & (i-1) == 0:        # true iff i is a power of 2

 

 9. Class

If a class does not inherit other classes, it should explicitly inherit object, even if it is an inner class

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

 This avoids some potential errors.

 

10 strings

Use formatting methods or the % operator to format strings, even if you know that all arguments are strings, to determine when to use + and when to use %.

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)

 Avoid using +, and += in loops, because strings are immutable and create a lot of unnecessary temporary objects. Instead, use ''.join to turn a list into a string at the end of the loop (or write each substring to the io.BytesIO buffer)

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>'

 Stick to one style of string notation

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.")

 

11. Files and sockets

But remember to close them when you are done with file and socket.

Unnecessary opening of a file, socket or file-like object has the following disadvantage.

1. Consume limited system resources, such as file handles.

2. Occupying a file will prevent other operations such as moving and deleting.

3. They are shared globally throughout the program, and closing will cause read and write exceptions.

Although it will be automatically destroyed when the object leaves the life cycle, it is not recommended to deal with it in this way. Here's why

1. First of all, there is no guarantee in this way, because different Python implementations use different memory management techniques, such as delayed memory reclamation.

2. Unexpected applications keep these objects unprocessed for longer periods of time.

The preferred way to manage files is to use the "with" statement

with open("hello.txt") as hello_file:
    for line in hello_file:
        print line

 File-like objects do not support the "with" statement, use contextlib.closing().

import contextlib

with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
    for line in front_page:
        print line

 Pythone 2.5 can use the "with" statement

from __future__ import with_statement

 

12 Use of TODO Comments

Use TODOs for temporary, short-term solutions to less-than-perfect code.

 

13 Format of Import

Different imports should be on different lines

Yes: import os
     import sys

No:  import os, sys

 When there are more introductions, it should be grouped. The grouping rules are as follows

1. Standard library

2. Third-party libraries

3. Application-level libraries

 

14 Attribute Access Control

But a property access is more complicated or should use method calls like get_foo(), and set_foo() instead.

 

15 Naming

module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_CONSTANT_NAME, global_var_name, instance_var_name, function_parameter_name, local_var_name.

 Guido-recommended naming

Type Public Internal
Packages lower_with_under  
Modules lower_with_under _lower_with_under
Classes CapWords _CapWords
Exceptions CapWords  
Functions lower_with_under() _lower_with_under()
Global/Class Constants CAPS_WITH_UNDER _CAPS_WITH_UNDER
Global/Class Variables lower_with_under _lower_with_under
Instance Variables lower_with_under _lower_with_under (protected) or __lower_with_under (private)
Method Names lower_with_under() _lower_with_under() (protected) or __lower_with_under() (private)
Function/Method Parameters lower_with_under  
Local Variables lower_with_under  

 

16 Main

In Python, pydoc and unit test require importable modules. Before executing your program, your code should always be checked, so as to avoid the main program not being called when your module is imported

 

def main():
      ...

if __name__ == '__main__':
    main()

 

17 Final words

Be consistent.

If you're editing code, take a moment to look at other codes to see their style, and be consistent with them.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326437487&siteId=291194637