老是忘记写文档被同事吐槽?试试文档即代码的方式,从函数注释自动生成接口
每天早上打开项目文件夹,总能看到同事在群里发消息:“这个接口的返回字段是啥来着?”然后一圈人开始翻代码。你打开自己三个月前写的模块,盯着密密麻麻的函数发呆。注释写的就一句话:“这个函数做数据转换”。具体怎么转、入参有哪些、返回什么格式,全凭猜。这事我自己干过太多次。后来被技术组长单独叫去谈话,他拿着我的接口文档说:“你这写的比我奶奶的菜谱还难懂”。
其实问题不复杂。写文档和写代码在开发阶段是割裂的。你写完代码,还得专门打开另一个工具写文档。一来二去,文档就落后了。有人试过用Swagger或者Postman自动生成文档,这些工具确实有用。但它们依赖的是代码里的装饰器或者请求样例。你改了函数名,忘了改装饰器里的描述,文档照样是错的。真正该作为文档来源的,是python函数自身。
python函数注释有个很实用的特性:类型提示和文档字符串。type hints能标注参数类型、返回值类型,docstring能写具体说明。如果你把这两样用到位,再配合一个解析工具,就能直接生成可读的接口文档。这个思路叫“文档即代码”,文档和代码是同一个东西。你改代码的时候,注释就在旁边,顺手就能改。
具体怎么操作呢。举个例子:
def get_user_info(user_id: int) -> dict: '''
根据用户ID获取用户基本信息。
参数:
user_id: 用户的唯一标识数字。
返回:
包含用户姓名、邮箱、注册时间的字典。
'''
...
这段代码本身就包含了接口的全部信息。函数名是“获取用户信息”,参数是整型ID,返回值是字典。docstring里具体说明了字段含义。你不需要再去别处写一份文档。工具可以直接从这段注释里提取出接口文档。
常见的解析工具有Sphinx的autodoc,或者pydoc。它们能扫描你的python文件,找出所有函数的类型提示和docstring,生成html文档。如果你项目里用了flask框架,可以用flask-autodoc。它直接从flask路由对应的视图函数里提取文档。只要每个视图函数都有规范的docstring,文档就能自动更新。
我自己的项目里,给每个接口函数都规定了docstring模板。第一行写接口概述。第二行写HTTP方法。第三行写参数列表,每个参数单独一行,格式是“参数名: 类型 说明”。第四行写返回示例。第五行写错误码。看起来像这样:
def create_order( user_id: int,
product_list: list,
address: str
) -> dict:
'''
创建新订单。
POST /orders
参数:
user_id: 用户ID,整数。
product_list: 商品列表,每个元素是商品ID和数量的字典。
address: 收货地址字符串。
返回:
成功时返回订单ID和状态。失败时返回错误信息。
错误码:
400: 参数校验失败
500: 服务端异常
'''
这样写三个月后,同事需要查接口时,直接在项目根目录跑一条命令:python -m pydoc -w your_module。一个浏览器页面就弹出来,所有接口都有。
你有可能会担心,这样写起来是不是比原来更费事。实际用下来,写几个接口就习惯了。特别是当你被问烦了的时候。你想想看,原来回答一次同事的问题至少浪费5分钟。花30秒把docstring写完整,可能给自己省下几十次被问的功夫。 不写文档的真正成本不是写的时间,而是反复沟通的时间。
团队里可以统一一个约定:每个新函数都带着完整的类型提示和docstring。代码评审时把注释也算进去。发现注释不全,打回去重写。一个月之后,你会发现同事之间关于接口的信息确认变少了。
还有一个细节。不要在注释里写废话。比如“这个函数用于获取用户信息”这种套话没意义。要写别人真正需要的信息:参数取值范围、边界情况、有什么坑。比如某个接口的分页参数默认是20条,但业务上可能要求最多100条。这个限制要写进注释。如果返回的数据里某个字段为空字符串是什么意思,也要写清楚。好的文档应该让调用者不需要翻代码。
这样生成的文档还有一个好处:可以和代码一起提交到版本控制。你修改了接口,注释跟着改,提交记录里能看到变更记录。后续接手你代码的人,看git历史就能知道某个接口参数为什么改了。文档和代码的版本同步,这个价值比想象的大。
试试看,从明天开始,给每个新写的函数都加上完整的docstring。运行一次自动生成工具,把生成的文档分享到团队群里。同事的反应可能让你意外。
夜雨聆风