文档章节

如何规范书写文档说明(Docstring) -- PEP 257

Lu_Castiel
 Lu_Castiel
发布于 2017/10/17 21:51
字数 2386
阅读 855
收藏 0

正文

  • 引言
  • 理论基础
  • 详细说明
    • 什么是文档说明
    • 单行的文档说明
    • 多行的文档说明
    • 处理文档说明缩进格式
  • 参考和补充说明
  • 版权
  • 鸣谢

引言

这个PEP文件是关于Python文档说明的书写语义和约定。

理论基础

这个PEP协议的目的是标准化文档说明的高级结构:里面有个包含说明,怎么去描述(不在其内创建任何的标记语法)。这个PEP秀逸包含约定,而不是法规或语法。


"有个通用的约定应该是可维护的、清晰可懂的、满足一致性的,同时也应该是好的编程习惯的基础。它不会违背你的意愿来强制要求你遵循那些规则。这就是Python!" -- Tim Peter写于comp.lang.python,2001-06-16

不按照约定来书写,最差的结果是你写的代码会比较难看,不美观。同时有些软件对约定(规范)比较重视,遵循这些规范才能得到好的结果。

详细说明

什么是文档说明?

一个文档说明是一个字符串,它出现在一个模块,函数,类或方法的定义的第一个语句。这样的文档说明即为该对象的__doc__特殊属性。

所有的模块,或对于被一个模块导入的函数和类都应该有文档说明。公共方法(包括__init__构造函数)也应该有文档说明。一个包可以在其包目录下存放其(模块的文档说明)init.py文件。

说明字符串通常出现在Python代码中的任意位置,这个代码也可以看做文档。他们既不能由Python编译器识别,也无法向运行时的对象属性那些被访问(即不分配给__doc__),但两种额外的文档说明,可以通过软件工具提取:

  1. 在一个模块、类或__init__方法的顶层的一个简单申明后立即出现的字符串--“属性文档说明”
  2. 在其他文档说明后立即出现的字符串--“补充文档说明”

想获取关于属性和补充文档说明的详细描述,请查阅PEP 258,"Docutils Design Specification"(文档工具设计说明)

XXX 提及的2.2版本的文档说明特性

为了满足一致性,常用3个双引号"""quotes"""来包裹文档说明。如果你在文档说明里使用了反斜杠\,使用r"""quotes""""来包裹。对于那些使用了Unicode文档说明的,使用u""""quotes"""来包裹。

有2种形式的文档说明:单行和多行文档说明。

单行文档说明

单行的说明文档是十分明显的一种类型。将说明描述字符串写入一行即可。比如说:

def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root
    if _kos_root: return _kos_root
    ...

说明:

  • 三个引号使用频繁,即便字符串可以写在一行内。这易于后期扩展。
  • 单行的3个双引号应在一行,看上去更美观
  • 在文档说明字符串前后没有空行
  • 文档说明应以句号结尾的一段语句。它以一个命令规定了函数或方法的结果,而不是描述;例如,不要写“Returns the pathname ...”
  • 单行文档说明不应该时一个"说明"去重申函数/方法的参数。不要像这样:
def function(a, b):
    """function(a, b) -> list"""

上面的这种类型的文档说明只适用于c函数(例如内建函数)这样的无法内省的函数。然而,return值的类型无法由内省决定,因此这需要被注意。对于这种文档说明较好的形式应该是:

def function(a, b):
    """Do X and return a list."""
多行文档说明

多行文档说明包含一个概要行(如单行文档说明那样),然后接一个空行,然后是更详细的说明。这种概要行应该使用动态索引工具来使用;让它在一行显示是十分重要的,并且使用空行来与其他的文档说明分割开。这个概要行可能与右边的3个双引号在同一行或在下一行。整个文档说明跟第一行那样缩进排版。

在所有的文档说明后插入一个空白行(一行或多行),类文档——一般来说,类的方法是由一个单一的空行隔开,文档说明需要有一个空行来开始第类的一个方法。

当一个脚本调用时使用了不正确或缺少参数(或是一个“H”选项,在“帮助”),其文档说明(一个独立的程序)应打印其使用方法信息。这样的文档说明应该包含脚本的功能和命令行语法、环境变量和文件。使用信息可以相当详细(有几个屏幕满),对于新用户正确使用命令,以及对高级用户的所有选项和参数的完正的快速引用应该足够了。

一个模块的文档说明一般应列出由模块导入的类,异常和功能(以及任何其他对象),并对应的使用一个单行的概要。(这些概要一般会比对象的文档说明提供更少的细节)。一个包的文档说明(即包的__init__ .py模块的文档说明),还应该列出由包导入的的模块和子包。

一个函数或方法的文档说明应该总结其行为和记录其参数,返回其值(S),附带作用,抛出的异常和调用时的限制(所有这些如果适用)。可选参数应被表示。无论关键字参数是否为接口的一部分它应该记录。

一个类的文档说明应该总结其行为并列出其公共方法和实例变量。如果这个类是一个子类,有额外的接口,该接口应分别列出(在文档字符串)。类的构造函数应该记录在文档说明的__init__方法。单独的方法应该由自己的文档说明记录。

如果一个类的子类及其行为主要是继承自该类,它的文档说明应该提到这点并总结其差异。用动词“override”表明一个类方法代替父类的方法并且它不调用父类的方法;用动词“extend”,表示一个子类的方法调用父类的方法(除了它自己的行为)。

不要在运行的文本中使用Emacs的约定方法大写函数或方法的参数。Python是大小写敏感,并且参数名可以使用关键字参数,所以文档说明应该记录正确的参数名。最好是在一个单独的行中列出每个参数。例如:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    ...

除非整个文档说明在一行中,否则将后面的引号单独放一行。可以使用Emacs的fill-paragraph命名创建中格式。

处理文档说明的缩进

文档说明处理工具将文档说明的第二行和之后的行的缩进除去,等于将第一行后的所有非空白行的碎金最小化。第一行的任意缩进(即到第一个换行符)是不明显的,要被删除的。文档说明的后面的行的相对缩进保留。空白行应该从文档的开始和结束处删除。

由于代码比文字更精确,这里是算法的实现:

def trim(docstring):
    if not docstring:
        return ''
    # Convert tabs to spaces (following the normal Python rules)
    # and split into a list of lines:
    lines = docstring.expandtabs().splitlines()
    # Determine minimum indentation (first line doesn't count):
    indent = sys.maxint
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    # Remove indentation (first line is special):
    trimmed = [lines[0].strip()]
    if indent < sys.maxint:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    # Strip off trailing and leading blank lines:
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    # Return a single string:
    return '\n'.join(trimmed)

在这个例子中的文档说明串包含两个换行符并因此有3行。第一行和最后一行是空白的:

def foo():
    """
    This is the second line of the docstring.
    """

举例说明:

>>> print repr(foo.__doc__)
'\n    This is the second line of the docstring.\n    '
>>> foo.__doc__.splitlines()
['', '    This is the second line of the docstring.', '    ']
>>> trim(foo.__doc__)
'This is the second line of the docstring.'

下面的2个函数的文档说明是一致的:

def foo():
    """A multi-line
    docstring.
    """

def bar():
    """
    A multi-line
    docstring.
    """

参考和补充说明

序号说明及连接
[1]PEP 256, Docstring Processing System Framework, Goodger (http://www.python.org/dev/peps/pep-0256/)
[2](1, 2) PEP 258, Docutils Design Specification, Goodger (http://www.python.org/dev/peps/pep-0258/)
[3]http://docutils.sourceforge.net/
[4]http://www.python.org/dev/peps/pep-0008/
[5]http://www.python.org/sigs/doc-sig/

版权

本文档在公共域中存放

鸣谢

这个“规范”的文字大多来自于Python Style Guide[4],由Guido van Rossum编写。

本文借鉴了Python Doc-SIG [5]文档。感谢过去和现在的所有成员。

来源:https://github.com/python/peps/blob/master/pep-0257.txt


本文是https://www.python.org/dev/peps/pep-0257/一文的中文翻译版,由castiel-Lu翻译,水平有限,翻译的可能有些问题,但应该不影响阅读。本文可以自由转载,不对之处希望可以email我(18367826960@163.com) -- 2017-10-17


© 著作权归作者所有

Lu_Castiel
粉丝 4
博文 87
码字总数 124222
作品 0
衢州
其他
私信 提问
Python中必读的PEP提案

什么是PEP PEP 是 Python 增强提案(Python Enhancement Proposal)的缩写。社区通过PEP来给 Python 语言建言献策,每个版本你所看到的新特性和一些变化都是通过PEP提案经过社区决策层讨论、投...

刘志军
2018/08/08
0
0
Python代码规范和命名规范

前言 Python 学习之旅,先来看看 Python 的代码规范,让自己先有个意识,而且在往后的学习中慢慢养成习惯 一、简明概述 1、编码 如无特殊情况, 文件一律使用 UTF-8 编码 如无特殊情况, 文件头...

blackfoxya
2018/07/23
57
0
PEP8 Python 编码规范整理

PEP8 Python 编码规范 一 代码编排 1 缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。 2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行...

guoswcfl
2018/06/29
0
0
SonarQube Python 1.6 和 SonarQube PL/SQL 2.8 发布

SonarQube PL/SQL 2.8 发布,主要更新如下: Avoid using DELETE or UPDATE without a WHERE clause Do not declare a variable more than once in a given scope (PLS-00371) SELECT * sho......

oschina
2016/07/21
832
0
[雪峰磁针石博客]python代码风格指南(PEP8中文版)

本文给出主Python版本标准库的编码约定。CPython的C代码风格参见PEP7。 本文和PEP 257 文档字符串标准改编自Guido最初的《Python Style Guide》, 并增加了Barry的GNU Mailman Coding Style ...

磁针石
2018/08/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
2.4K
15
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
41
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
40
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
61
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部