Python中函数文档字符串docstring的编写规范详解

 更新时间:2026年07月27日 08:36:16   作者:星河耀银海  
Python函数文档字符串(docstring)是代码的重要组成部分,它作为函数的使用说明书帮助开发者理解函数功能,本文详解介绍了Python文档字符串的规范,三大风格对比及实战技巧,帮你轻松提升代码可读性,告别协作时的沟通成本

一、开篇:代码是写给人看的

好的代码自己会说话,而docstring(文档字符串)就是帮代码"说话"的工具。一个函数如果没有docstring,调用者就只能去读源码或者猜它的用法。

对比有和没有docstring的区别:

# ❌ 没有docstring——只能猜
def calc(a, b, mode=1):
    if mode == 1:
        return a + b
    elif mode == 2:
        return a - b
    else:
        return a * b

# ✅ 有docstring——一目了然
def calc(a: float, b: float, mode: int = 1) -> float:
    """对两个数执行指定的运算。

    Args:
        a: 第一个操作数
        b: 第二个操作数
        mode: 运算模式,1=加法,2=减法,其他=乘法

    Returns:
        运算结果

    Raises:
        TypeError: 当操作数不是数字时
    """
    if mode == 1:
        return a + b
    elif mode == 2:
        return a - b
    else:
        return a * b

docstring是函数、类、模块的"使用说明书"。更重要的是,Python的help()函数和众多文档生成工具都依赖docstring。写好docstring,是对自己(三个月后的你)和同事最大的善意。

二、docstring的基本规则

2.1 位置和格式

# docstring的基本规则:
# 1. 放在函数/类/模块的第一行(def/class之后的第一条语句)
# 2. 用三引号包裹("""或''')
# 3. 可以使用多行

def greet(name: str) -> str:
    """向指定的人打招呼。"""
    return f"你好,{name}!"

# 访问docstring
print(greet.__doc__)  # 向指定的人打招呼。

# help()查看——更友好的展示
# help(greet)
# 输出:
# Help on function greet in module __main__:
#
# greet(name: str) -> str
#     向指定的人打招呼。

# ⚠️ docstring必须是字符串字面量,不能是变量
# def bad():
#     doc = "文档"   # 这不是docstring!是普通的字符串赋值
#     pass

2.2 单行docstring

# 适用场景:函数功能简单明了

def add(a: int, b: int) -> int:
    """返回a和b的和。"""
    return a + b

def is_even(n: int) -> bool:
    """判断一个整数是否为偶数。"""
    return n % 2 == 0

# PEP 257规范:
# - 三引号在同一行开始和结束
# - 使用句号结尾
# - 描述函数的功能(做什么),而不是实现(怎么做)
# - 使用命令式语气:"返回..."而不是"这个函数返回..."

2.3 多行docstring

# 适用场景:函数逻辑复杂,需要详细说明

def fetch_user_data(
    user_id: int,
    fields: list[str] | None = None,
    include_inactive: bool = False,
    timeout: int = 30
) -> dict | None:
    """从数据库获取用户数据。

    根据用户ID查询用户信息。如果提供了fields参数,
    只返回指定的字段。默认不包含已停用的用户。

    Args:
        user_id: 用户唯一标识符
        fields: 需要返回的字段列表,None表示返回所有字段
        include_inactive: 是否包含已停用的用户
        timeout: 查询超时时间(秒)

    Returns:
        包含用户数据的字典,如果用户不存在则返回None。
        字典的键取决于fields参数。

    Raises:
        ValueError: 当user_id小于等于0时
        TimeoutError: 查询超时时
        DatabaseError: 数据库连接失败时

    Examples:
        >>> fetch_user_data(123)
        {'name': '张三', 'email': 'zs@test.com', 'age': 25}

        >>> fetch_user_data(123, fields=['name', 'age'])
        {'name': '张三', 'age': 25}

        >>> fetch_user_data(999)
        None
    """
    if user_id <= 0:
        raise ValueError("user_id必须大于0")
    # ... 实际实现 ...
    return {"name": "张三", "email": "zs@test.com", "age": 25}

三、三大docstring风格对比

3.1 Google风格(推荐!)

def send_notification(
    user: str,
    message: str,
    *,
    channel: str = "email",
    priority: str = "normal",
    attachments: list[str] | None = None,
    retry_count: int = 3
) -> bool:
    """向用户发送通知消息。

    支持多种通知渠道,消息发送失败时自动重试。
    高优先级消息会绕过用户的免打扰设置。

    Args:
        user: 接收通知的用户名或用户ID
        message: 通知内容,支持纯文本
        channel: 通知渠道,可选值:\"email\"、\"sms\"、\"push\"、
            \"wechat\"。(默认:\"email\")
        priority: 优先级,可选值:\"low\"、\"normal\"、\"high\"、
            \"urgent\"。(默认:\"normal\")
        attachments: 附件文件路径列表,None表示无附件
            (默认:None)
        retry_count: 失败重试次数(默认:3)

    Returns:
        True表示发送成功,False表示所有重试均失败。

    Raises:
        ValueError: 当channel或priority值不合法时
        FileNotFoundError: 当附件文件不存在时

    Example:
        >>> send_notification("张三", "您的订单已发货",
        ...                   channel="sms", priority="high")
        True

        >>> send_notification("李四", "服务器告警",
        ...                   channel="push", priority="urgent")
        True
    """
    valid_channels = {"email", "sms", "push", "wechat"}
    if channel not in valid_channels:
        raise ValueError(f"无效的通知渠道: {channel}")
    # ... 实际实现 ...
    return True

3.2 NumPy风格

def calculate_statistics(
    data: list[float],
    *,
    skip_na: bool = True,
    percentiles: list[int] | None = None
) -> dict:
    """计算数据集的描述性统计。

    Parameters
    ----------
    data : list of float
        待分析的数据列表。
    skip_na : bool, optional
        是否跳过NaN值。默认值为True。
    percentiles : list of int or None, optional
        需要计算的百分位数列表。默认值为None,
        不计算百分位数。

    Returns
    -------
    dict
        包含统计结果的字典,包含以下键:
        - "count": 样本数量
        - "mean": 平均值
        - "std": 标准差
        - "min": 最小值
        - "max": 最大值
        - "percentiles": 百分位数结果(如果指定了percentiles)

    Raises
    ------
    ValueError
        当data为空列表时。

    Examples
    --------
    >>> calculate_statistics([1.0, 2.0, 3.0, 4.0, 5.0])
    {'count': 5, 'mean': 3.0, 'std': 1.58, 'min': 1.0, 'max': 5.0}
    """
    pass

3.3 Sphinx/reStructuredText风格

def validate_email(email: str) -> bool:
    """验证邮箱地址格式是否合法。

    :param email: 待验证的邮箱地址字符串
    :type email: str
    :return: 邮箱格式合法返回True,否则返回False
    :rtype: bool
    :raises TypeError: 当email不是字符串时

    验证规则:
    1. 包含恰好一个 @ 符号
    2. @ 前后都有字符
    3. @ 后面部分包含一个 .

    ::

        >>> validate_email("user@example.com")
        True
        >>> validate_email("invalid-email")
        False
    """
    if not isinstance(email, str):
        raise TypeError("email必须是字符串")
    parts = email.split("@")
    return len(parts) == 2 and all(parts) and "." in parts[1]

3.4 风格选型建议

# 💡 风格选择建议:
# 
# Google风格 → 推荐!最流行,可读性最好,VS Code/PyCharm原生支持
# NumPy风格 → 科学计算/数据分析项目首选
# Sphinx风格 → 用Sphinx生成文档的项目,传统选择
#
# 关键不是用哪种风格,而是在项目中保持一致!

四、docstring在实际开发中的应用

4.1 doctest:用docstring做测试

# doctest模块可以从docstring中提取>>>示例并自动测试!

def add(a: int, b: int) -> int:
    """返回两个整数的和。

    >>> add(2, 3)
    5
    >>> add(-1, 1)
    0
    >>> add(0, 0)
    0
    """
    return a + b

def factorial(n: int) -> int:
    """计算n的阶乘。

    >>> factorial(0)
    1
    >>> factorial(1)
    1
    >>> factorial(5)
    120
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n必须是非负整数
    """
    if n < 0:
        raise ValueError("n必须是非负整数")
    if n <= 1:
        return 1
    return n * factorial(n - 1)

# 运行doctest
if __name__ == "__main__":
    import doctest
    doctest.testmod()
    print("所有doctest通过!")

4.2 模块和类的docstring

"""
用户管理模块

提供用户注册、登录、信息查询和管理功能。

Classes:
    User: 用户数据模型
    UserManager: 用户管理服务
    AuthenticationError: 认证异常

Functions:
    create_user: 创建新用户
    authenticate: 验证用户身份

Usage:
    >>> from user_management import create_user
    >>> user = create_user("zhangsan", "password123",
    ...                    email="zs@test.com")
    >>> print(user.name)
    张三
"""

class UserManager:
    """用户管理服务类。

    负责处理用户的创建、查询、更新和删除操作。
    所有数据库操作通过此类统一管理。

    Attributes:
        db_connection: 数据库连接对象
        cache: 用户信息缓存
        max_cache_size: 最大缓存条目数

    Example:
        >>> manager = UserManager(db_conn)
        >>> user = manager.get_user(123)
        >>> manager.update_user(123, {"age": 30})
    """
    def __init__(self, db_connection):
        """初始化用户管理器。"""
        pass

五、总结

docstring是程序员给未来的自己(和同事)写的信。好的docstring让代码"自带说明书"。

核心要点:

  1. 所有公共函数/类/模块都应该有docstring
  2. PEP 257是Python docstring的官方规范
  3. Google风格是目前最流行的选择
  4. doctest让docstring既是文档又是测试
  5. 一致性比风格更重要——项目内统一风格

docstring应该写什么:

  • 函数做什么(不是怎么做)
  • 参数的含义和类型
  • 返回值的含义
  • 可能抛出的异常
  • 简单的使用示例

docstring不应该写什么:

  • 显而易见的实现细节
  • 版本历史(交给git)
  • 谁写的、什么时候写的(交给git blame)

以上就是Python中函数文档字符串docstring的编写规范详解的详细内容,更多关于Python文档字符串的资料请关注脚本之家其它相关文章!

相关文章

  • JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解

    JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解

    这篇文章主要介绍了JetBrains PyCharm(Community版本)的下载、安装和初步使用教程,本文图文并茂给大家介绍的非常详细,对大家的学习和工作具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2020-03-03
  • pycharm配置当鼠标悬停时快速提示方法参数

    pycharm配置当鼠标悬停时快速提示方法参数

    这篇文章主要介绍了pycharm中配置当鼠标悬停时快速提示方法参数,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • Flask创建并运行数据库迁移的实现过程

    Flask创建并运行数据库迁移的实现过程

    Flask创建并运行数据库迁移的过程是一个涉及多个步骤的操作,旨在帮助开发者在开发过程中管理数据库模式的变化,而不需要手动地删除和重建数据库表,从而避免数据丢失,以下是一个详细的步骤说明,需要的朋友可以参考下
    2024-09-09
  • 如何使用python的xml库实现自闭合标签

    如何使用python的xml库实现自闭合标签

    文章介绍了作者编写一个URDF格式化插件的初衷,目的是解决sw2urdf导出的URDF文件格式混乱的问题,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-01-01
  • python实现搜索文本文件内容脚本

    python实现搜索文本文件内容脚本

    这篇文章主要为大家详细介绍了python实现搜索文本文件内容的脚本,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • Python机器学习pytorch交叉熵损失函数的深刻理解

    Python机器学习pytorch交叉熵损失函数的深刻理解

    这篇文章主要为大家介绍了Python机器学习中对交叉熵损失函数的深刻理解,文中作出了详细易懂的讲解,有需要的朋友可以借鉴参考下希望能够有所帮助
    2021-10-10
  • 通过Python实现对SQL Server 数据文件大小的监控告警功能

    通过Python实现对SQL Server 数据文件大小的监控告警功能

    这篇文章主要介绍了通过Python实现对SQL Server 数据文件大小的监控告警,本文给大家分享问题报错信息及解决方案,需要的朋友可以参考下
    2021-04-04
  • python 最简单的实现适配器设计模式的示例

    python 最简单的实现适配器设计模式的示例

    这篇文章主要介绍了python 最简单的实现适配器设计模式的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Mac PyCharm中的.gitignore 安装设置教程

    Mac PyCharm中的.gitignore 安装设置教程

    这篇文章主要介绍了Mac PyCharm中的.gitignore 安装设置教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • Python求离散序列导数的示例

    Python求离散序列导数的示例

    今天小编就为大家分享一篇Python求离散序列导数的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07

最新评论