Python 编码风格指南(收藏)

发布时间:2020-05-12编辑:脚本学堂
这是一篇有关python编程风格的指南性文章,介绍了一些规范的、良好的python编码风格,有需要的朋友参考下。

本节内容:
python 编码风格指南

Horin|贺勤
Email: horin153@msn.com
Blog: http://blog.csdn.net/horin153/

PEP:  8
Title:  Style Guide for Python Code
Version:  54700
Url:  http://www.Python.org/dev/peps/pep-0008/

译者:为了尽可能使译文保留原滋原味,译者尽可能进行直译;保留原始文档的布局、缩进、换行风格 (阅读时请最大化);尽量不在译文中穿插个人评注。
    对有疑问的翻译,在译文后面的括号中给出原文;对部分标题和专业词汇,同时给出原文和译文,以方便阅读。
 
    感谢《Python 开发编码规范》一文及其作者,本文的很多句子、段落是对该文的直接引用、或者略加修改。参见:
    http://wiki.woodpecker.org.cn/moin/PythonCodingRule
 
    尽管逐词逐句都进行过认真推敲,但囿于能力,本文仍有很多不当、甚至错误的翻译;请读者海涵,并敬请指正;联系方式:horin153@msn.com。

介绍
    这篇文档所给出的编码约定,适用于在主要的 Python 发布版本中组成标准库的Python 代码。在 Python 的 C 实现中 C 代码风格指南的描述,请查阅姊妹篇PEP 7。

    这篇文档改编自 Guido 最初的《Python Style Guide》一文。并从《Barry's style guide》中添加了部分内容。在有冲突的地方,Guide 的风格规则应该是符合本 PEP
    的意图。这篇 PEP 可能仍是不完善的 (实际上,它可能永远不会完美)。

令人讨厌的小人物身上愚蠢的一致性
(A Foolish Consistency is the Hobgoblin of Little Minds)

    Guido 的主要洞察力 (key insights) 之一是:代码更多是用来读而不是写。故本指南致力于改善 Python 代码的可读性、使不同的 (wide spectrum) Python 代码
    保持一致性。正如 PEP 20 所说的可读性计算 (Readability counts)。

    风格指南是关于一致性的。风格一致对本指南是重要的,对一个项目更重要。在一个模块、或者函数内保持 (代码风格) 一致最重要。

    但最重要的是:知道何时会不一致 -- 有时只是没有实施风格指导。当有疑惑时,运用你的最佳判断。看看别的例子,然后决定怎样看起来更好。并且要不耻下问!

    打破一条既定规则的两个好理由:

    (1) 当应用这条规则时将导致代码可读性下降,即便对某人来说,他已经习惯于按这条规则来阅读代码了。

    (2) 为了和周围的代码保持一致而打破规则 (也许是历史原因) -- 虽然这也是个清除其他混乱的好机会 (在真正的 XP 风格中)。

代码布局 (Code lay-out)

  缩进 (Indentation)

    每级缩进用 4 个空格。

    为避免与旧代码混淆,可继续采用 8 个空格宽的 tab 缩进。

  Tab 还是空格 (Tabs or Spaces)?

    绝不要混合使用 tab 和空格。

    最流行的 Python 缩进方式是仅使用空格,其次是仅使用制表符。混合着制表符和空格缩进的代码将被转换成仅使用空格。调用 Python 命令行解释器时使用 -t 选项,
    可对代码中不合法的混用制表符和空格发出警告 (warnings)。使用 -tt 时警告将变成错误。这些选项是被高度推荐的。

    对新项目,强烈推荐只用空格,而不是用 tabs。大多数编辑器拥有使之易于实现的功能。

  最大行宽 (Maximum Line Length)

    限制所有行的最大行宽为 79 字符。

    周围仍然有许多设备被限制在每行 80 字符;而且,窗口限制在 80 个字符,使将多个窗口并排放置成为可能。在这些设备上使用默认的折叠 (wrapping) 方式看起来有
    点丑陋。 因此,请将所有行限制在最大 79 字符。对顺序排放的大块文本 (文档字符串或注释 (docstrings or comments)),推荐将长度限制在 72 字符。

    折叠长行的首选方法是使用 Python 支持的圆括号、方括号 (brackets) 和花括号(braces) 内的行延续。如果需要,你可以在表达式周围增加一对额外的圆括号,但是
    有时使用反斜杠看起来更好。确认恰当地缩进了延续的行。
   
    一些例子:
  

复制代码 代码示例:

  class Rectangle(Blob):

        def __init__(self, width, height,
                     color='black', emphasis=None, highlight=0):
            if width == 0 and height == 0 and
               color == 'red' and emphasis == 'strong' or
               highlight > 100:
                raise ValueError("sorry, you lose")
            if width == 0 and height == 0 and (color == 'red' or
                                               emphasis is None):
                raise ValueError("I don't think so")
            Blob.__init__(self, width, height,
                          color, emphasis, highlight)

  空行 (Blank Lines)

    用两行空行分割顶层函数和类的定义。

    类内方法的定义用单个空行分割。

    额外的空行可被用于 (保守的 (sparingly)) 分割相关函数群 (groups of related functions)。在一组相关的单句 (related one-liners) 中间可以省略空行(例如一组哑元 (dummy implementations))。

    在函数中使用空行时,请谨慎的用于表示一个逻辑段落 (logical sections)。

    Python 接受 contol-L (即 ^L) 换页符作为空白符 (whitespace);许多工具视这些字符为分页符 (page separators),因此在你的文件中,可以用它们来为相关片段(sections) 分页。

  编码 (Encodings) (PEP 263)

    Python 核心发布中的代码应该始终使用 ASCII 或 Latin-1 编码(又名ISO-8859-1)。

    使用ASCII的文件不必有译码 cookie (coding cookie)。 Latin-1 仅当注释或文档字符串涉及作者名字需要 Latin-1 时才被使用;另外使用 x 转义字符是在字符串中包含非 ASCII 数据的首选方法。

导入 (Imports)

    - 通常应该在单独的行中导入,例如:
      

复制代码 代码示例:

  Yes: import os
             import sys

        No:  import sys, os

      但是这样也是可以的:
     

复制代码 代码示例:
   from subprocess import Popen, PIPE

    - Imports 通常被放置在文件的顶部,仅在模块注释和文档字符串之后,在模块的全局变量和常量之前。

      Imports应该按照如下顺序成组安放:
      1. 标准库的导入
      2. 相关的第三方包的导入
      3. 本地应用/库的特定导入

      你应该在每组导入之间放置一个空行。

      把任何相关 __all__ 说明的放在 imports 之后。

    - 对于内部包的导入是非常不推荐使用相对导入的。对所有导入总是使用包的绝对路 径。即使现在 PEP 328 [7] 在 Python 2.5 中被完整实现了,其 explicit  relative imports 的风格也是不推荐的。绝对导入能更好的移植 (portable),通常也更易读。

    - 从一个包含类的模块中导入类时,通常可以写成这样:
   

复制代码 代码示例:
     from myclass import MyClass
        from foo.bar.yourclass import YourClass

      如果这样写导致了本地名字冲突,那么就这样写:
     

复制代码 代码示例:
   import myclass
        import foo.bar.yourclass

      并使用 "myclass.MyClass" and "foo.bar.yourclass.YourClass"

在表达式和语句中的空格 (Whitespace in Expressions and Statements)

  宠物的烦恼 (Pet Peeves)
  (注:即无伤大雅的小问题)

    避免在下述情形中使用无关的空格:

    - 紧挨着圆括号、方括号和花括号:
      Yes: spam(ham[1], {eggs: 2})
      No:  spam( ham[ 1 ], { eggs: 2 } )

    - 紧贴在逗号、分号或冒号前:
      Yes: if x == 4: print x, y; x, y = y, x
      No:  if x == 4 : print x , y ; x , y = y , x

    - 紧贴着函数调用的参数列表前的开式括号:
      Yes: spam(1)
      No:  spam (1)

    - 紧贴在索引或切片 (indexing or slicing) 开始的开式括号前:
      Yes: dict['key'] = list[index]
      No:  dict ['key'] = list [index]

    - 在赋值 (或其他) 运算符周围的用于和其他语句对齐的一个以上的空格:
     

复制代码 代码示例:

Yes:
          x = 1
          y = 2
          long_variable = 3

      No:

          x             = 1
          y             = 2
          long_variable = 3

其他建议 (Other Recommendations)

    - 始终在这些二元运算符两边放置一个空格:
     

复制代码 代码示例:
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
          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)

    - 不要在用于指定关键字参数 (keyword argument) 或默认参数值的 '=' 号周围使用
      空格。
     

复制代码 代码示例:
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)
 

    - 复合语句 (Compound statements) (多条语句写在同一行) 一般不推荐。
    

复制代码 代码示例:

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

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

    - 虽然有时可以在 if/for/while 的同一行跟一小段代码,但绝不要对多条子句
      (multi-clause statements) 也这样做。也避免折叠这样的长行。

      最好不要 (Rather not):
      

复制代码 代码示例:
    if foo == 'blah': do_blah_thing()
          for x in lst: total += x
          while t < 10: t = delay()
 

      明确不要 (Definitely not):
     

复制代码 代码示例:

     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()

注释 (Comments)