当前位置: 代码网 > it编程>前端脚本>Python > Python中函数文档字符串docstring的编写规范详解

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

2026年07月27日 Python 我要评论
一、开篇:代码是写给人看的好的代码自己会说话,而docstring(文档字符串)就是帮代码"说话"的工具。一个函数如果没有docstring,调用者就只能去读源码或者猜它的用法。对

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

好的代码自己会说话,而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文档字符串的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com