PEP-8小记

0x00 前言

代码可读性是代码的可修改性的一个重要影响因素。

就Python而言,最富盛名的的编码风格指南就是PEP 8(Python Enhancement Proposals)

本文简单记录/翻译PEP-8的一些经典实践和见解。

0x01 PEP-8笔记

“愚蠢的一致性是心胸狭窄的妖怪“

A Foolish Consistency is the Hobgoblin of Little Minds

编码风格指南的宗旨是提升代码的可读性,并使得Python代码风格能够趋于一致性。一个风格指南就是提出一种使开发者代码风格保持某种一致的倡议。

然而,当风格指南并不实用的时候,根据自己的判断力作出最佳选择,多看别人的案例并决定一个最佳的。不要只是为了迎合某种风格指南(包括PEP)而破坏代码的向后兼容性。

代码布局

缩进

每个缩进层级使用4个空格。连续的行中应该把包裹的要素垂直对齐,使用Python在括号、大括号内的隐式行连接,或者使用悬挂缩进(hanging indent)。使用悬挂缩进的时候需要考虑:第一行不应该有参数,并使用进一步的缩进表示这是一个延续行。

# Correct:

# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

# Hanging indents should add a level.
foo = long_function_name(
    var_one, var_two,
    var_three, var_four)
# Wrong:

# Arguments on first line forbidden when not using vertical alignment.
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# Further indentation required as indentation is not distinguishable.
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)
Tabs或空格

空格是首选的缩进方法,制表符应该仅用于与已经使用制表符缩进的代码保持一致。Python不允许混合使用制表符和空格进行缩进。

换行符应该在二进制操作符之前还是之后?

将换行符放在二进制操作符是曾经风靡一时的风格,但是这对于可读性来说有几种损害:操作符在屏幕上通常分布在不同的列上,并且每个操作符远离其操作数(在操作数的前一行),这会是得眼睛需要做额外的工作判断哪些项是他们要加或减的。

# Wrong:
# operators sit far away from their operands
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)
# Correct:
# easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)
空行

顶部的函数和类定义之间隔两行空行;

类中的方法定义由一个空行包围;

在函数中有节制地使用空行来表示逻辑节

源文件编码

核心Python发行版中的代码应该始终使用UTF-8,并且不应该有编码声明。

在标准库中,非utf -8编码只能用于测试目的。尽量使用非ascii字符,最好只用于表示地点和人名。如果使用非ascii字符作为数据,请避免有噪声的Unicode字符

导入模块
  • 导入模块不要在同一行,按如下方式导入:

    # Correct:
    import os
    import sys
    

    反面案例:

    # Wrong:
    import sys, os
    

    但如下风格也是可以的:

    # Correct:
    from subprocess import Popen, PIPE
    
  • 模块导入应该总是在在文件顶端进行,具体位置在对模块的注释(comment)和文档字符串(docstring)之后,在全局变量和常量之前。

    导入顺序建议为按如下分组导入:

    1. 标准库的导入

    2. 第三方库导入

    3. 本地应用/库导入

    每一组模块之间应该有一个空行

  • 推荐使用绝对导入,因为这通常更具有可读性并且会表现得更好

    import mypkg.sibling
    from mypkg import sibling
    from mypkg.sibling import example
    
  • 应该避免通配符导入(from <module> import *),除非是有正当理由:如将内部接口开放位公共API。

字符串引号

单引号和双引号是一样的,PEP不会对此进行推荐,你只需要选择一条规则并且遵守就好。当字符串包含单引号或双引号时,使用另一种引号以避免使用反斜杠,这可以提高可读性。

表达式或语句间的空格

避免无关的空格,比如说在如下场景中:

  • 紧跟着圆括号、方括号、大括号内。

    # Correct:
    spam(ham[1], {eggs: 2})
    
    # Wrong:
    spam( ham[ 1 ], { eggs: 2 } )
    
  • 在逗号和右括号之间

    # Correct:
    foo = (0,)
    
    # Wrong:
    bar = (0, )
    

    

  • 在逗号、冒号、分号前:

    # Correct:
    if x == 4: print(x, y); x, y = y, x
    
    # Wrong:
    if x == 4 : print(x , y) ; x , y = y , xs
    
  • ……

0x02 代码检查工具

可通过源代码错误和代码质量检查器辅助检查代码可读性

pylint

pylint通过与PEP8标准进行一致性对比,为待检查代码打分。常见消息码:

R: 违反“良好实践”原则
C: 违反编程规范
W: 不严重的编程问题
E: 严重的编程问题(可能是错误)
F: 致命错误,pylint无法运行

注意:pylint默认检查最大行长为100,而PEP8建议行最大字符数为79,若需要对齐PEP8,可通过参数调整检查规则,如

 pylint --max-line-length=79 Projects/project1/fake_name.py

pycodestyle

Flake8

pydocstring

文档字符串检查工具,检查文档字符串是否符合PEP257标准

 pip install pydocstyle

0x03 Python高级编程中关于可读性的部分内容笔记

关于变量

常量、公有和私有变量。但是Python的常量仅仅是通过命名约定(大写+下划线)来标记,而非像java、c++等通过const关键字来定义常量,所以Python的常量不是真正意义上的常量,“常量”是可以被修改的。

0x04 编程规范更多参考

  • PEP 8编程规范

  • PEP 257指导准则

  • Google编程规范

  • Google编程规范范例

  • Numpy文档字符串标准

  • Numpy文档字符串范例

  • reStructuredText模块及文档

CoolCats
CoolCats
理学学士

我的研究兴趣是时空数据分析、知识图谱、自然语言处理与服务端开发