Python 的文档字符串(docstring)是函数、类或模块顶部用三引号包裹的字符串,运行时可以通过 __doc__ 属性或 help() 函数查看。它本质上是一份可读的接口说明,帮助调用者了解参数、返回值、异常和使用示例。很多开发者刚写完一个函数,过两周就忘了参数含义,而规范的 docstring 能彻底解决这个问题。
本文基于实际项目经验,梳理 docstring 的编写规则、主流风格、各部分写法以及配套自动化工具,适合新手小白和需要统一团队规范的开发者。
一、docstring 的基本规则
1. 位置:必须是函数/类/模块定义后的第一条语句,前面不能有赋值或计算等代码。- def process(data):
- """处理输入数据。"""
- pass
复制代码 2. 引号:单引号或双引号均可,团队统一即可。推荐双引号。
3. 写法:多行时第一行写概述,空一行后写详细说明。单行则不加空行。- def max_value(items):
- """返回列表中的最大值。
-
- 如果列表为空,返回 None。
- """
- pass
复制代码
二、四大主流风格与选择建议
Python 社区没有强制标准,但有三种主流风格:Google 风格、NumPy 风格和 reST 风格。
1. Google 风格(推荐新手)
结构清晰,可读性好,被 TensorFlow、PyTorch 等主流项目广泛使用。- def calculate_area(width, height):
- """
- 计算矩形的面积。
-
- Args:
- width (float): 矩形的宽度,必须大于 0。
- height (float): 矩形的高度,必须大于 0。
-
- Returns:
- float: 矩形的面积。
-
- Raises:
- ValueError: 当 width 或 height 小于等于 0 时抛出。
- """
- if width <= 0 or height <= 0:
- raise ValueError("宽度和高度必须大于 0")
- return width * height
复制代码
2. NumPy 风格
科学计算领域的标准,NumPy、Pandas 均采用。使用连续的短横线分隔段落,纯文本下视觉清晰。- def calculate_area(width, height):
- """
- 计算矩形的面积。
-
- Parameters
- ----------
- width : float
- 矩形的宽度,必须大于 0。
- height : float
- 矩形的高度,必须大于 0。
-
- Returns
- -------
- float
- 矩形的面积。
- """
- pass
复制代码
3. reST(Sphinx)风格
适合需要生成 HTML/PDF 文档的大型项目,Sphinx 原生支持。- def calculate_area(width, height):
- """
- 计算矩形的面积。
-
- :param width: 矩形的宽度,必须大于 0
- :type width: float
- :param height: 矩形的高度,必须大于 0
- :type height: float
- :returns: 矩形的面积
- :rtype: float
- """
- pass
复制代码
建议:新手直接选 Google 风格,团队统一即可。
三、每个部分的编写要点
1. 概述(必写):用一句话说明函数做什么,而不是怎么做。例如 "从指定 URL 获取 JSON 数据" 而不是 "使用 requests 库发送 GET 请求"。
2. Args(有参数则写):每个参数占一行,写类型、含义、默认值或可选值。
3. Returns(有返回值则写):写返回的类型和含义。如果返回多种类型,列清楚条件。若返回复杂结构,列出字段。
4. Raises(有异常则写):只写函数主动抛出的异常,常见为 ValueError、TypeError、KeyError 等。
5. Examples(强烈建议写):提供可运行的示例,可直接用 doctest 模块测试。
6. Notes / See Also(按需写):写注意事项、参考其他函数等。
四、不同场景的示例
简单工具函数:- def is_palindrome(s):
- """
- 判断字符串是否为回文(忽略大小写和空格)。
-
- Args:
- s (str): 待判断的字符串。
-
- Returns:
- bool: 是回文返回 True,否则返回 False。
-
- Examples:
- >>> is_palindrome("racecar")
- True
- >>> is_palindrome("A man a plan a canal Panama")
- True
- """
- cleaned = s.lower().replace(" ", "")
- return cleaned == cleaned[::-1]
复制代码
类的 docstring:- class DataLoader:
- """
- 数据加载与预处理工具类。
-
- 支持从 CSV、JSON、Parquet 格式加载数据,
- 并提供缺失值填充、类型转换等预处理功能。
-
- Attributes:
- data (pd.DataFrame): 加载后的数据。
- filepath (str): 数据文件路径。
- encoding (str): 文件编码格式。
- """
- def __init__(self, filepath, encoding="utf-8"):
- self.filepath = filepath
- self.encoding = encoding
- self.data = None
复制代码
带类型注解的函数(推荐组合使用):- from typing import Optional, List, Dict
- def get_top_users(data: List[Dict[str, object]], n: int = 10, sort_by: str = "score") -> List[Dict[str, object]]:
- """
- 获取排名前 N 的用户。
-
- Args:
- data: 用户数据列表,每个元素是包含用户信息的字典。
- n: 返回的用户数量,默认为 10。
- sort_by: 排序字段名,默认为 score。
-
- Returns:
- 排序后的前 N 个用户数据列表。
-
- Raises:
- KeyError: 当 sort_by 指定的字段不存在时抛出。
- ValueError: 当 n 小于 1 时抛出。
- """
- pass
复制代码 注意:类型注解写在函数签名里,docstring 重点写业务含义,不用重复类型。
五、模块级 docstring
每个 Python 文件顶部也应有 docstring,说明模块用途、依赖和使用方式。- """
- 数据处理工具模块。
- 提供数据清洗、格式转换、缺失值处理等常用功能。
- 主要服务于用户行为分析项目。
- 模块依赖:
- - pandas >= 1.5
- - numpy >= 1.23
- 使用方式:
- from data_utils import clean_dataframe, parse_dates
- df = clean_dataframe(raw_data)
- """
复制代码
六、docstring 与注释的区别
- docstring:写给调用者,说“做什么”,位于函数/类/模块第一行,可通过 help() 查看。
- 注释:写给维护者,说“为什么这么写”,在代码内部任意位置,help() 看不到。
一句话:docstring 是接口说明,注释是实现细节。
七、自动化工具推荐
1. pydoc:Python 自带,命令行查看或生成 HTML 文档。- pydoc your_module
- pydoc -w your_module
复制代码
2. Sphinx:专业文档生成工具,安装后初始化,可用 sphinx-apidoc 自动从 docstring 生成 API 文档。- pip install sphinx
- sphinx-quickstart
- sphinx-apidoc -o docs/ src/
复制代码
3. docformatter:自动格式化 docstring 排版。- pip install docformatter
- docformatter --in-place your_file.py
复制代码
4. pydocstyle:检查 docstring 是否符合 PEP 257 等规范,可加入 pre-commit hook 或 CI 流水线,不规范的直接报错。- pip install pydocstyle
- pydocstyle src/
- pydocstyle utils.py
复制代码
八、写好 docstring 的 5 个原则
1. 说做什么,不说怎么做。
2. 有参数就写参数,有返回就写返回。
3. 给可运行的 Examples,既能当文档又能当测试。
4. 与类型注解配合,类型交给注解,含义交给 docstring。
5. 风格统一,整个项目只选一种风格。
养成写 docstring 的习惯,是对未来自己和他人的尊重。配合自动化工具,让规范自动执行,不依赖人的自觉。 |