养成良好的Python的编码风格 - Go语言中文社区

养成良好的Python的编码风格


【Introduction】

在编写Python代码的过程中,良好的编码风格和一致的编码格式,对于我们创建具有很好可读性以及维护代码是非常有好处的。
这里,把我的Python编码过程的习惯总结一下,这些习惯大部分是来自于PEP 8 style guide 和 Google Python Style Guide。

【Terminology】

module——一个以.py结尾的文件,里面包含python代码。
package——包含了多个module的文件夹,里面包含了一个特殊的module,就是__init__.py
function——python语句组成的代码段,将运行结果返回给调用者。
class——用户创建对象的模板,通常包含一些method用于操作类的实例
method——类中定义的function
attribute——与对象有关的一个value
object——类的实例,具有类所定义的attribute和method
global variable——在模块级别定义的变量

【Naming Conventions】

All names must be meaningful.

Package Names

     For package names use lowercase. 

     Package names should be kept short.

Module Names

     For module names use lower_case_with_underscores. 

     Modules names should be short. Underscores can be used if it improves readability.

Function Names

    For function names use lower_case_with_underscores.

    Where possible use a verb-noun format e.g. get_event_id() name.

    Use one leading underscore only for non-public functions. 

        Yes: assert_unscrambled(), detect_motion(), _press_button()

        No: serial_nr(), cssn_nr(), do_stuff(), x()

Class Names

    For class names use the CamelCase convention.

   Class names for internal use should also have a leading underscore.

        Yes:class Service(object),WebDriver(RemoteWebDriver)

Variable Names

    For global and local variable names use lower_case_with_underscores

Method Names

    For method names use lower_case_with_underscores.

    Try to use a meaningful name that describes what the method does.

    Use one leading underscore only for non-public methods.

Constant Names

    For constants use UPPER_CASE_WITH_UNDERSCORES.

    Constants should be defined with module scope and situated just after the import statements.

    If you see something declared using this naming convention don't change the value.

    Note that there are no true constants in Python. However, by using this naming convention you are saying that the value of the identifier ought not to change. In other words, the naming convention communicates to other programmers that they should not change the value.

Argument Names

1. Each argument should be on a separate line

2. Try to use meaningful names, no magic numbers:

    Yes: results = st.CompareImage(ref_image,
                                                         None,
                                                         rect = (541,429,123,49), 
                                                         timeout = 5,
                                                         percent = 90,
                                                         savescreencap = st.SaveScreenCap.Never,
                                                         slotNo = self.slot_nr)

     No: flag = st.CompareImage(file, None, (541,429,123,49), 5,90,savescreencap = st.SaveScreenCap.Never,slotNo = self.slot_nr)

3. Always use 'self' for the first argument to instance methods.

4. Always use 'cls' for the first argument to class methods.

【Naming Examples】

【Comments】

If you are unsure whether you need to add a comment to a particular piece of code, a good rule of thumb is to ask yourself whether you would need to explain the code in a code review. If the answer is yes then add a comment.

1.Keep comments up-to-date. Comments that contradict the code are worse than no comments. Always make a priority of keeping the comments up-to-date when the code changes.

2.Comments should be written in English.

【DocStrings】

A docstring is a string literal that occurs as the first statement in a package, module, function, class, or method definition.

1.Write docstrings for all packages, modules, functions, classes, and methods.

2.Docstrings are not necessary for non-public methods, but you should have a comment that describes what the method does.

【One-line Docstrings】

One-liners are for really obvious cases. They should really fit on one line. For example:

def sf_set_debit_limit(serial_nr, limit):
    """Short form of the set_debit_limit() command."""

1.Triple quotes are used even though the string fits on one line. This makes it easy to later expand it.

2.The closing quotes are on the same line as the opening quotes. This looks better for one-liners.

3.There's no blank line either before or after the docstring.

【Multi-line Docstrings】

Multi-line docstrings consist of a summary line just like a one-line docstring, followed by a blank line, followed by a more elaborate description. For example:

def GetCryptoPeriod():
    """
    Return crypto period based on ECMG_MAX_COMP_TIME resource value

    Retrieves ECMG_MAX_COMP_TIME resource value and following calculation: x/1000 +1
    Returns an integer
    """

It is important that the summary line fits on one line and is separated from the rest of the docstring by a blank line.

The summary line may be on the same line as the opening quotes or on the next line.

The entire docstring is indented the same as the quotes at its first line

【Function Docstrings】

For very simple functions a one-line docstring can be sufficient. When a multi-line docstring is used it should include the following sections:

 Parameters
 Returns
 Returns Type (optional)
 Usage
 Sphinx directives (optional)

Add a blank line between sections

Add indentation when starting the content of a section

Note the parameters section syntax: a space, a dash, a space, argument name, a space, a dash, a space, description

It should be possible to paste the Usage section into a python interactive window

An example function docstring: 

def find_elements_by_id(self, id_):
        """
        Finds multiple elements by id.

        :Args:
         - id_ - The id of the elements to be found.

        :Usage:
            driver.find_element_by_id('foo')
        """

【Code Layout】

【Indentation】

1.Use 4 spaces per indentation level.

2.Spaces-only are strongly recommended over tabs.

3.Never mix tabs and spaces.

【Blank Lines】

1.Separate top-level function and class definitions with two blank lines.

2.Method definitions inside a class are separated by a single blank line.

3.Use blank lines in functions, sparingly, to indicate logical sections.

【Imports】

1.Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

2.Imports should be on separate lines

Yes: import os
        import sys

No:  import sys, os

3. Do not use wildcard imports.

No: from constants import *

4. Only use from x import y where x is a package and y is a module.

Yes: from lib import stb

No:  from lib.soap import getConfigurationItem

5. If you use import module as alias then make sure that the alias is meaningful.

Yes: import lib.guicmdlib as kms_gui

No:  import lib.guicmdlib as x

Whitespace in Expressions and Statements

Avoid uneccessary whitespace in the following situations: 

1. Immediately inside parentheses, brackets or braces.

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

2. 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

3. Immediately before the open parenthesis that starts the argument list of a function call:

Yes: spam(1)
No:  spam (1)

4. Immediately before the open parenthesis that starts an indexing or slicing:

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

5. More than one space around an assignment (or other) operator to align it with another.

Yes:

          x = 1
          y = 2
          long_variable = 3

 No:

          x             = 1
          y             = 2
          long_variable = 3

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

7. Use spaces around arithmetic operators:

      Yes:

          i = i + 1
          submitted += 1
          x = x * 2 - 1
          hypot2 = x * x + y * y
          c = (a + b) * (a - b)

No:

          i=i+1
          submitted +=1
          x = x*2 - 1
          hypot2 = x*x + y*y
          c = (a+b) * (a-b)

8. Don't use spaces around the '=' sign when used to indicate a keyword argument or a default parameter value.

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)

9. Compound statements (multiple statements on the same line) are generally discouraged.

Yes:

          if foo == 'blah':
              do_blah_thing()
          do_one()
          do_two()
          do_three()

No:

          if foo == 'blah': do_blah_thing()
          do_one(); do_two(); do_three()

10. While sometimes it's okay to put an if/for/while with a small body on the same line, never do this for multi-clause statements.

No:

          if foo == 'blah': do_blah_thing()
          for x in lst: total += x
          while t < 10: t = delay()

          if foo == 'blah': do_blah_thing()
          else: do_non_blah_thing()

          try: something()
          finally: cleanup()

          do_one(); do_two(); do_three(long, argument,
                                       list, like, this)

          if foo == 'blah': one(); two(); three()

Programming Recommendations

1.Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators.

2.Do not write "if x" when you really mean "if x is not None" e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

3.Use class-based exceptions.

4.When raising an exception, use "raise ValueError('message')" instead of the older form "raise ValueError, 'message'".

5.For all try/except clauses, limit the 'try' clause to the absolute minimum amount of code necessary. This avoids masking bugs.

Yes:

          try:
              value = collection[key]
          except KeyError:
              return key_not_found(key)
          else:
              return handle_value(value)

      No:

          try:
              # Too broad!
              return handle_value(collection[key])
          except KeyError:
              # Will also catch KeyError raised by handle_value()
              return key_not_found(key)

6Use string methods instead of the string module.

7.Use .startswith() and .endswith() instead of string slicing to check for prefixes or suffixes.

Yes: if foo.startswith('bar'):

No:  if foo[:3] == 'bar':

8.Object type comparisons should always use isinstance() instead of comparing types directly.

Yes: if isinstance(obj, int): 
No: if type(obj) is type(1): 

9.When checking if an object is a string, keep in mind that it might be a unicode string too! In Python 2.3, str and unicode have a common base class, basestring, so you can do:

if isinstance(obj, basestring):

10.For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

Yes: if not seq:
     if seq:

No: if len(seq)
    if not len(seq)

11.Don't write string literals that rely on significant trailing whitespace. Such trailing whitespace is visually indistinguishable and some editors (or more recently, reindent.py) will trim them.

12. Don't compare boolean values to True or False using ==

        Yes:   if greeting:

        No:    if greeting == True:

        Worse: if greeting is True:

【Pylint】

Pylint is a python tool that can be used to check if a module satisfies a coding standard. It is recommended to use pylint in the Eclipse Pydev IDE.Pylint

Eclipe中进入Windows-Preferences-PyDev-Pylint:

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/liuchunming033/article/details/39644065
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-02-23 17:23:39
  • 阅读 ( 1306 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢