Litedoc: Python模块文档生成器
项目地址:Litedoc
谁有时间读你们这破文档.jpg
前言
有时候我在编写一些库的时候,大部分精力都放在了代码的编写上,而对于文档的编写却很少关注。 这样的话,很容易导致别人无法使用你的库,就连时间长了自己也会忘记自己写的这个库是干什么的。这是不好的。 但是编写文档也是个技术活,尤其是像我自己的库,有些类方法经常变化,若涉及文档引用往往不能及时更新或者漏掉东西。 而且纯手写的文档也很难保证格式的统一,这样的话,文档的可读性就会大打折扣。于是我就想,有没有什么办法能让工具自己读取代码,然后生成满足自己审美和需求的API文档呢? 具体就是,提取函数,类及其方法,属性等的注解和文档字符串,然后按照包的结构生成一份结构相似的文档。这样的话,文档就会随着代码的更新而更新,而且格式也会统一。
明确需求
- 能够自动读取代码结构
- 能自动解析注解和文档字符串
- 自定义文档模板且统一
- 内容与代码库保持最新
设计思路
代码结构读取
对于代码的读取,我选择使用ast模块对整个项目进行解析并生成抽象语法树。这样的话,我就结构化这些Python文件, 我们可以遍历ast
模块生成的抽象语法树,然后提取出我们需要的信息,比如函数,类,方法,属性等。然后自己定义一些数据结构来储存这些对象的信息。
文档字符串解析
这部分需要我们写一个解析器(parser),目前Python注释的风格有多种,其中reStructuredText
是比较常用的一种,而且也是Python官方推荐的一种。此外还有Google
风格,Numpy
风格等。 使用什么风格不是很重要,最重要的是我们需要把这些注释解析为一种统一的结构化的对象,每种风格注释无外乎都包含以下几种内容:
- 对象的描述
- 可调用对象的参数的描述
- 可调用对象的返回值的描述
- 异常的描述
- 示例描述
- ...
对每个token进行解析,我们可以得到一个结构化的对象,之所以要结构化处理,是因为不同风格的注释可能有不同的结构,我们需要把这些结构化的对象转换为一种统一的结构。 在渲染文档的时候,我们只需要根据这种统一的结构来渲染文档即可。相当于是把解析和渲染两部分模块解耦了。
自定义文档模板
这一步就是很简单的字符串处理了,我们只需要把解析出来的结构化对象填充到我们的模板中即可。 假设有一个Function对象,它有name, description, args, returns和注释文档等属性,我们只需要把这些属性填充到我们的模板中即可。
保持文档与代码库同步
- 开发:参考大部分前端框架,它们都提供了一种热重载的功能,即代码更新后,文档也会更新。这里我们可以使用
watchdog
启动一个进程,监控文件变化,当某个.py文件发生变化时,对应的md文件也会更新。 - 构建:可以配合CI/CD工具,每次代码提交后,自动构建文档。github action可以很方便的实现这个功能。
总结
编写过程中,我查阅了部分PEP规范,并在Google风格注释上进行了扩展支持,使文档更加符合阅读习惯。
在开发过程中我了解到了nb_autodoc这个库,为我提供了很多灵感。
配合该工具,我只需要在代码中写规范注释即可,文档会自动生成,这样的话,我就可以专注于代码的编写了。
借助一些文档web框架,我们可以在注释中写一些对应的markdown扩展语法,实现更多的效果。