最近看了不少代码,也写了不少代码,所以在看和写之间发现了很多的问题,真的是很多,至少从我的认识来看,有几个地方有很大的改进空间,这里不准备把所有的问题都列举出来,所以就先挑选一个比较明显得来和大家聊聊。回顾流行开源项目的成功,除了功能上的刚需之外,文档也是必不可少的一个环节,没有良好文档的开源项目几乎不可能说是流行的,因为很少人会因为你说了一句使用我的项目就可以怎么怎么样就傻不溜秋得用你的。从我以前开源的项目中大家可能会发现一个比较大的问题就是文档工作做得确实不咋地。
项目中的文档我认为可以分为直接文档和间接文档两部分,直接文档就是 README/Read the docs 这类的可以直接阅读的文档,而间接文档就是代码中的注释了。别人在阅读你的项目的时候,首先,直接文档可以让大家对你的项目有一个直观的认识,知道你的项目是干嘛的,大概的实现思路/算法是怎样的;而代码注释就是别人在验证你的项目是否真如你文档所说,实现得是否良好的一种参考,所以两种文档都是很重要的。
在 Python 中,因为 docs comment 的存在,可以让这两种文档归一,其实就是将 comment 抽离出来转化为可以直接阅读的 Document,虽然这有点理想化,但是在一定程度上减少了我们编写文档的难度和复杂度。本文就如何编写这样的 Comment 进行一个简单的总结,同时也是对自己的一个改进。
Google coding-style guide
玩 Python 的同学应该都知道 Python 没有一个业界的代码规范,而 PEP8 这些也不并不能完全对我们的开发起到很好得规范和知道作用。反而,看现在很多人的代码,发现 google coding style 的接受度更高,所以,不妨多参考一些。
模块注释
在 Python 中,每个文件其实都是一个自成模块,所以我就称文件注释为模块注释,模块注释一般就是解释该模块是干嘛用的,以及如何使用该模块等信息,同时,在构建工具之后就变成了文档的主要内容了。不妨我们来看下 requests 的注释:
可以发现其实这份注释还是比较清晰的,可以分为几个部分,分别是:
- 功能介绍
- 使用 Demo 示例以及参数/返回值等
- 版权之类的说明
这算是一份比较标准化的注释了,至于注释的风格,我们可以参照 reStructuredText Primer 这份说明进行练习。
类注释
类的注释的话又稍微复杂一些,除了必要的类说明和使用示例之外,你还需要对类的够赞函数进行参数描述,因为 python 的构造函数是 __init__
,而我们通常文档是直接看类的说明,所以这里写在类上很重要!如果你的类存在必要的公共属性,需要对外暴露出来,那么也应该标注出来。我们可以参考一下 Flask 的示例:
前面洋洋洒洒得写了很多说明,然后后面就对构造函数的参数进行了描述。
函数注释
函数的注释应该是最复杂的,因为我们不仅仅最函数的功能进行描述,还要关注函数的参数和返回值,参数又需要描述参数的意义,还要描述参数的类型,返回值也是如此,所以我们也来看看 Celery 的一个示例:
这里只有对函数的解释,注意事项还有返回值,除此之外,我们还经常用的有:
- Args
- Returns
- Raises
从源码构建文档
当我们将我们的源码的注释都注释得七七八八了,觉得是时候编一份文档看看效果如何了,那么你是应该看看下面的介绍啦!
当然,我还是参考一些流行项目的做法,看看人家的文档是怎么做的,说实话,我看过的这么多个项目的文档中,Flask 确实是写得比较好的,当然,Django 的也是不错,不过它的文档过于人工修饰,从源码中还原度没有那么高。所以这里我以 Flask 为例来看看开源项目是如何做注释文档化的。
要想了解自然先尝试一遍,不是太麻烦,将 Flask 的源码 clone 下来之后,只需要简单得使用 make docs
,稍等片刻,你就讲得到 docs 的编译版本,默认你会得到 html 版本,位置就在源码目录的 _build/html
目录下。但是,看看 Makefile 再看看 docs
目录你可能又会疑惑,因为 docs
里面已经放置了 rst 文件了,所以这个时候的问题就是如何从 py
文件中抽离 rst
文件!
其实这些问题对于一些工具来说都是很简单的,Flask 用的是 sphinx,这个工具被 Python 世界的大多数开源项目所青睐,所以也成为了一个事实上的文档标准。使用 sphinx 可以让我们轻松得解决两个问题:
- 抽离 python 注释
- 将代码文档化
操作过程只是两句命令就可以解决的问题:
- 将代码中的文档注释抽离出来:
sphinx-apidoc -F -o docs flask
- 将文档转换成 html 形式:
sphinx-build -b html . _build/html
- 或者在第一步的基础上更直接点:
make html
- 或者在第一步的基础上更直接点:
这样,你就将你之前的努力都转化成可以被人直观接受的文档了!这里是我转化过的一个示例:
很多时候我们可能对默认转化出来的文档不是很满意,但是,没关系,我们可以在完成第一步之后编辑 rst 文件,然后调整到我们满意之后,再 make html
,这样就会好很多!