Python学习笔记 - Python编程规范

前言

        俗话说:“没有规矩不成方圆”。编程工作往往都是一个团队协同进行,因而一致的编码规范非常重要,这样写成的代码便于团队中的其他人阅读,也便于编写者自己以后阅读。

        本文的Python语言编程规范借鉴了Python官方的PEP8编码规范和谷歌Python编码规范。

参考链接

PEP 8 – Style Guide for Python Code

Google Style Guide for Python Code

一、命名规范

        程序代码中到处都是标识符,因此取一个一致并且符合规范的名字非常重要。Python中命名规范采用多种不同方式。不同的代码元素命名不同,下面将分类说明。

  • 包名:全部小写字母,中间可以由点号(.)隔开,不推荐使用下划线。作为命名空间,包名应该具有唯一性,推荐采用公司或组织域名的倒置,如 com.apple.quicktime.v2。
  • 模块名:全部小写字母,如果是多个单词构成,可以用下划线隔开,如 dummy_threading。
  • 类名:采用大驼峰法命名,如 SplitViewController。
  • 异常名:异常属于类,命名和类名命名相同,但应该使用 Error 作为后缀,如 FileNotFoundError。
  • 变量名:全部小写字母,如果由多个单词构成,可以用下划线隔开。如果变量应用于模块或函数内部,则变量名可以由单下划线开头;变量为类内部私有成员变量时则变量名可以由双下划线开头。不要命名双下划线开头和结尾的变量名,这是Python保留的。另外,避免使用小写 L、大写 O 和大写 I 作为变量名。
  • 函数名和方法名:全部小写字母,如果由多个单词构成,可以用下划线隔开。如果是类内的方法名, 则可以由单下划线开头。如 balance_account()、_balance_account()。
  • 常量名:全部大写字母,如果由多个单词构成,可以用下划线隔开。如 YEAR、WEEK_OF_MONTH。

说明】大驼峰法命名是驼峰命名法的一种,驼峰命名是指混合使用大小写字母来命名。驼峰命名分为小驼峰法和大驼峰法。小驼峰法就是第一个单词全部小写,后面的单词首字母大写,如 myRoomCount;大驼峰法是第一个单词的首字母也是大写,如 ClassRoom。

建议】可以去上网查阅一些著名大厂编写的Python编程规范文档,比如说华为的,讲得很详细。

二、注释规范

Python中的注释的语法有三种:单行注释、多行注释和文档注释。

2.1  文件注释

        文件注释就是在每一个文件开头添加注释,采用多行注释。文件注释通常包含如下信息:版权信息、文件名、所在模块、作者信息、历史版本信息、文件内容和作用等。

下面是一个文件注释的示例:

# 
# 版权所有 2015 XXXX科技有限公司
# 许可证查看 LICENSE.TXT 文件
# 描述:
#    实现日期基本功能
# 历史版本:
# 2022-4-5: 创建 张三
# 2022-4-20:添加socket库
# 2022-5-6: 添加math库
# 

上述注释只是提供了版权信息、文件内容和历史版本等信息,文件注释要根据实际情况包含内容。

2.2  文档注释

        文档注释就是文档字符串,注释内容能够生成API帮助文档,可以使用 Python 官方提供的 pydoc 工具从 Python 源代码文件中提取这些信息,也可以生成 HTML 文件。所有公有的模块、函数、类和方法都应该进行文档注释。

        文档注释规范有些“苛刻”。文档注释推荐使用一对三重双引号(""")包裹起来,注意不推荐使用三重单引号(''')。文档注释应该位于被注释的模块、函数、类和方法内部的第一条语句。如果文档注释一行就能够注释完成,结束的三重双引号也在同一行。如果文档注释很长,第一行注释之后要留一个空行,然后剩下的注释内容换行要与开始三重双引号对齐,最后结束的三重双引号要独占一行,并与开始三重双引号对齐。

【示例】文档注释示例:

"""Return an ex-parrot."""     # ---1


"""Return a foobang            # ---2

Optional plotz says to frobnicate the bizbaz first. # ---3
"""                                                 # ---4

        上述第1处注释是只有一行的文档注释,第2处注释是多行的文档注释,注意它的第一行后面是一个空行,第3处接着进行注释,它要与开始三重双引号对齐。第4处是结束三重双引号,它独占一行,而且要与开始三重双引号对齐。

2.3  代码注释

        程序代码中处理文档注释时还需要一些关键的地方添加代码注释,文档注释一般是给一些看不到源代码的人看的帮助文档,而代码注释是给阅读源代码的人参考的。代码注释一般采用单行注释和多行注释。

【示例】

# Base32 encoding/decoding must be done in Python  ---1
_b32alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
_b32tab2 = None
-b32rev = None

def b32encode(s):
    """Encode the bytes-like object s using Base32 and return a bytes object.
    """
    global _b32tab2
    """
    Delay the initialization of the table to not waste memory  ---2
    if the function is never called                            ---3
    """
    if _b32tab2 is None:
        b32tab2 = [a + b for a in b32tab2 for b in b32tab]
        b32tab = None

    if not isinstance(s, bytes_types):
        s = memoryview(s).tobytes()
    leftover = len(s) % 5
    # Pad the last quantum with zero bits if necessary           ---4

        上述代码第1处和第4处都是单行注释,要求与其后面的代码具有一样的缩进级别。第2、3处是多行注释,注释时要求与其后面的代码具有一样的缩进级别。

2.4  使用 TODO 注释

PyCharm 等 IDE 工具都为源代码提供了一些特殊的注释,就是在代码中加一些标识,便于IDE工具快速定位代码,TODO 注释就是其中的一种。TODO注释虽然不是官方所提供的,但是主流IDE工具也都支持TODO注释。有TODO注释说明此处有待处理的任务,或代码没有编写完成。

【示例】

import com.pkg2.hello as module1
from com.pkg2.hello import z

y = 20

# TODO 声明函数
print(y)          # 访问当前模块变量y
print(module1.y)  # 访问com.pkg2.hello模块变量y
print(z)          # 访问com.pkg2.hello模块变量z

这些注释可以在PyCharm工具的TODO视图查看,在PyCharm视图中选择TODO,单击其中的TODO就可以跳转到TODO注释处了。

Python学习笔记 - Python编程规范_第1张图片 图1  打开TODO注释

三、导入规范

导入语句总是放在文件顶部,位于模块注释和文档注释之后,模块全局变量和常量之前。每一个导入语句只能导入一个模块。示例代码如下:

推荐

import re
import struct
import binascii

不推荐

import re, struct, binascii

但是如果from...import 后面跟多个代码元素是可以的。

from codep import CommandCompiler, compile_command

        导入语句应该按照从通用到特殊的顺序分组,顺序是:标准库—>第三方库—>自己模块。每一组之间有一个空行,而且组中模块是按照英文字母顺序排序的。

import io          # 先导入标准库中的模块
import os
import pkgutil
import platform
import re
import sys
import time

from html import unescape     # 再导入第三方库中的模块

from com.pkg1 import example  # 最后导入自己的模块

四、代码排版

代码排版包括空行、空格、断行和缩进等内容。代码排版内容比较多,工作量大,也非常重要。

4.1  空行

空行用以将逻辑不相关的代码段分隔开,以提高阅读性。下面是使用空行的规范。

(1)import 语句块前后保留两个空行

示例代码如下,其中(1)(2)处和(3)(4)处是两个空行。

# Copyright 2022 Google, Inc. All Rights Reserved.
# Licensed to PSF under a Contributor Agreement.

"""Abstract Base Classes (ABCs) according to PEP 3119."""
# ---1
# ---2
from _weakrefset import WeakSet
# ---3
# ---4
...

(2)函数声明之前保留两个空行。

示例代码如下,其中(1)(2)处是两个空行。

from _weakrefset import WeakSet
# ---1
# ---2
def abstractmethod(funcobj):
    funcobj.__isabstractmethod__ = True
    return funcobj

(3)类声明之前保留两个空行。

示例代码如下,其中(1)(2)处是两个空行。

# ---1
# ---2
class abstractclassmethod(classmethod):
    __isabstractmethod__ = True
    
    def __init__(self, callable):
        callable.__isabstractmethod__ = True
        super().__init__(callable)

(4)方法声明之前保留一个空行。

示例代码如下,其中(1)处是一个空行。

class abstractclassmethod(classmethod):
    __isabstractmethod__ = True
    # ---1
    def __init__(self, callable):
        callable.__isabstractmethod__ = True
        super().__init__(callable)

(5)两个逻辑代码块之间应该保留一个空行。

4.2  空格

代码中的有些位置是需要有空格的,这个工作量也很大。下面是使用空格的规范。

(1)赋值符号 “=” 前后要各有一个空格。

a = 10
b = 20

(2)所有的二元运算符都应该使用空格与操作数分开。

a = a1 + a2
b += 10
c = c1 * c2

(3)一元运算符:减法运算符 “-” 和 按位取反运算符 “~” 跟操作数之间没有空格。

a = 10
b = -a
c = ~b

(4)括号内不要有空格,Python中的括号包括小括号“()”、中括号“[]”和大括号“{}”。

【推荐】

doque(cat[1], {dog: 2}, [])

【不推荐】

doque(cat[ 1 ], { dog: 2 }, [ ])

(5)不要在逗号、分号、冒号前面有空格,而是要在它们后面有一个空格,除非该字符已经是行尾了。

【推荐】

if x == 88:
    print(x, y)

x, y = y, x

【不推荐】

if x == 88 :
    print(x , y)

x , y = y , x

(6)参数列表、索引或切片的左括号前不应有空格。

【推荐】

doque(1)
dogs['key'] = list[index]

【不推荐】

doque (1)
dogs ['key'] = list [index]

4.3  缩进

        4个空格常被作为缩进排版的一个级别。虽然在开发时程序员可以使用制表符进行缩进,而默认情况下一个制表符等于8个空格,但是不同IDE工具中一个制表符与空格对应个数会有不同,所以不要使用制表符缩进。

        代码块的内容相当于首行缩进一个级别(4个空格)

4.4  断行

        一行代码中最多120个字母,对于文档注释和多行注释时一行最多80个字符,但是如果注释中包含URL地址可以不受这个限制。否则,如果超过则需断行,可以依据下面的一般规范断行。

(1)在逗号后面断行。

bar = long_function_name(name1, name2,
                         name3, name4)
def long_function_name(var_one, var_two,
                       var_three, var_four):

(2)在运算符前面断行。

name1 = name2 * (name3 + name4 
                         - name5) + 4 * name6

(3)尽量不要使用续行符 “\”,当有括号(包括小括号、中括号和大括号)则在括号中断行,这样就可以不使用续行符。

def long_function_name(var_one, var_two,
                       var_three, var_four):
    return var_one + var_two + var_three \     # ---1
            + var_four

name1 = name2 * (name3 + name4 
                         - name5) + 4 * name6

bar = long_function_name(name1, name2,
                         name3, name4)

foo = {
    long_dictionary_key: name1 + name2
                         - name3 + name4 - name5
}

c = list[name2 * name3
        + name4 - name5 + 4 * name6]

        上述代码第1处使用了续行符进行断行,其他的断行都是在括号中实现的,所以省略了续行符。有时为了省略续行符,会将表达式用小括号括起来,如下代码所示。

def long_function_name(var_one, var_two,
                       var_three, var_four):
    return (var_one + var_two + var_three
            + var_four)

【提示】在Python中反斜杠 “\” 可以作为续行符使用,告诉解释器当前行和下一行是连续在一起的。但在小括号、中括号和大括号中续行是隐式的。

参考

《Python从小白到大牛(第1版-2018)》第5章 - Python编码规范

《疯狂Python讲义(2018.12)》

《Python编程:从入门到实践(2016.7)》

你可能感兴趣的