正文:
- 引言
- 理论基础
- 详细说明
- 什么是文档说明
- 单行的文档说明
- 多行的文档说明
- 处理文档说明缩进格式
- 参考和补充说明
- 版权
- 鸣谢
引言
这个PEP文件是关于Python文档说明的书写语义和约定。
理论基础
这个PEP协议的目的是标准化文档说明的高级结构:里面有个包含说明,怎么去描述(不在其内创建任何的标记语法)。这个PEP秀逸包含约定,而不是法规或语法。
"有个通用的约定应该是可维护的、清晰可懂的、满足一致性的,同时也应该是好的编程习惯的基础。它不会违背你的意愿来强制要求你遵循那些规则。这就是Python!" -- Tim Peter写于comp.lang.python,2001-06-16
不按照约定来书写,最差的结果是你写的代码会比较难看,不美观。同时有些软件对约定(规范)比较重视,遵循这些规范才能得到好的结果。
详细说明
什么是文档说明?
一个文档说明是一个字符串,它出现在一个模块,函数,类或方法的定义的第一个语句。这样的文档说明即为该对象的__doc__特殊属性。
所有的模块,或对于被一个模块导入的函数和类都应该有文档说明。公共方法(包括__init__构造函数)也应该有文档说明。一个包可以在其包目录下存放其(模块的文档说明)init.py文件。
说明字符串通常出现在Python代码中的任意位置,这个代码也可以看做文档。他们既不能由Python编译器识别,也无法向运行时的对象属性那些被访问(即不分配给__doc__),但两种额外的文档说明,可以通过软件工具提取:
- 在一个模块、类或__init__方法的顶层的一个简单申明后立即出现的字符串--“属性文档说明”
- 在其他文档说明后立即出现的字符串--“补充文档说明”
想获取关于属性和补充文档说明的详细描述,请查阅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