乐于分享
好东西不私藏

代码规范——PEP 8:注释与文档字符串

代码规范——PEP 8:注释与文档字符串

一、注释概述

注释是代码中用于解释说明的文字,帮助理解代码逻辑和意图。

# 这是单行注释
print("Hello, World!")

"""
这是多行注释
可以跨多行
"""

二、注释类型

2.1 行内注释

# ✅ 好的行内注释
name = "张三"# 用户名
age = 25# 用户年龄

# ❌ 不好的行内注释
name = "张三"# 赋值给name  # 多余说明

# ✅ 合适的行内注释(与代码至少隔两个空格)
items = [123]  # 初始化列表

# ❌ 不合适的行内注释
items = [123]#初始化列表  # 缺少空格

2.2 块注释

# ✅ 好的块注释
# 检查用户权限
# 如果是管理员,则允许所有操作
# 否则只允许查看
if user.is_admin:
    allow_all_operations()
else:
    allow_read_only()

# ❌ 不好的块注释
# 权限检查
if user.is_admin:  # 管理员权限
    allow_all_operations()  # 允许所有操作
else:  # 非管理员
    allow_read_only()  # 只读

2.3 文档字符串

# ✅ 模块文档字符串
"""用户管理模块,提供用户相关的功能。"""

# ✅ 类文档字符串
classUser:
"""用户类,表示系统中的用户信息。"""
pass

# ✅ 函数文档字符串
defget_user(user_id):
"""
    根据用户ID获取用户信息。

    Args:
        user_id (int): 用户ID

    Returns:
        dict: 用户信息字典
    """

pass

三、文档字符串格式

3.1 Google风格

defcalculate_average(numbers):
"""
    计算数字列表的平均值。

    Args:
        numbers (list): 包含数字的列表。

    Returns:
        float: 平均值。

    Raises:
        ValueError: 如果列表为空。

    Examples:
        >>> calculate_average([1, 2, 3, 4, 5])
        3.0
        >>> calculate_average([])
        Traceback (most recent call last):
        ...
        ValueError: 列表不能为空
    """

ifnot numbers:
raise ValueError("列表不能为空")
returnsum(numbers) / len(numbers)

3.2 NumPy风格

defcalculate_average(numbers):
"""
    计算数字列表的平均值。

    Parameters
    ----------
    numbers : list
        包含数字的列表。

    Returns
    -------
    float
        平均值。

    Raises
    ------
    ValueError
        如果列表为空。

    Examples
    --------
    >>> calculate_average([1, 2, 3, 4, 5])
    3.0
    """

ifnot numbers:
raise ValueError("列表不能为空")
returnsum(numbers) / len(numbers)

3.3 Sphinx风格

defcalculate_average(numbers):
"""
    计算数字列表的平均值。

    :param numbers: 包含数字的列表
    :type numbers: list
    :return: 平均值
    :rtype: float
    :raises ValueError: 如果列表为空

    Example::

        >>> calculate_average([1, 2, 3, 4, 5])
        3.0
    """

ifnot numbers:
raise ValueError("列表不能为空")
returnsum(numbers) / len(numbers)

四、注释最佳实践

4.1 解释意图而非实现

# ✅ 好的注释:解释为什么
# 使用二分查找提高性能
deffind_item(items, target):
pass

# ❌ 不好的注释:重复代码
# 遍历列表
deffind_item(items, target):
for item in items:  # 循环每个元素
if item == target:  # 比较是否相等
return item  # 返回找到的元素

4.2 更新注释

# ✅ 注释与代码保持一致
defcalculate_discount(price, discount_rate):
# 计算折扣价格:价格 * (1 - 折扣率)
return price * (1 - discount_rate)

# ❌ 注释过时
defcalculate_discount(price, discount_rate):
# 计算折扣价格:价格 / (1 + 折扣率)
return price * (1 - discount_rate)

4.3 避免冗余注释

# ✅ 代码自解释
defis_adult(age):
return age >= 18

# ❌ 冗余注释
defis_adult(age):
# 判断年龄是否大于等于18
return age >= 18

五、特殊注释

5.1 TODO注释

TODO: 添加输入验证
defprocess_data(data):
pass

# TODO(张三): 优化性能
defcalculate_total(items):
pass

TODO: 重构为更高效的算法 - 问题#123
defsort_data(data):
pass

5.2 FIXME注释

FIXME: 修复边界条件错误
defget_item(index):
return items[index]

FIXME: 临时解决方案,需要重构
deftemporary_fix():
pass

5.3 NOTE注释

NOTE: 这里使用缓存提高性能
defget_user(user_id):
if user_id in cache:
return cache[user_id]
    user = fetch_from_db(user_id)
    cache[user_id] = user
return user

NOTE: Python 3.8+ 支持
defprocess_data(data):
pass

5.4 BUG注释

BUG: 在某些情况下会溢出
defcalculate_large_numbers():
pass

BUG: 会抛出KeyError异常
defget_config_value(key):
return config[key]

六、实战案例

6.1 完整模块文档

"""
用户管理模块 - 提供用户相关的CRUD操作。

该模块包含用户创建、查询、更新和删除功能。
支持用户缓存和权限验证。

Example:
    >>> from user_manager import UserManager
    >>> manager = UserManager()
    >>> user = manager.create_user("张三", "zhangsan@example.com")
    >>> print(user.name)
    张三
"""


import logging
from typing importOptional

logger = logging.getLogger(__name__)


classUserManager:
"""用户管理器类。

    负责用户的所有操作,包括创建、查询、更新和删除。
    使用缓存提高查询性能。

    Attributes:
        cache: 用户缓存字典
        db: 数据库连接对象
    """


def__init__(self, db_connection):
"""
        初始化用户管理器。

        Args:
            db_connection: 数据库连接对象
        """

self.db = db_connection
self.cache = {}

defget_user(self, user_id: int) -> Optional[dict]:
"""
        根据ID获取用户信息。

        先从缓存查找,如果不存在则从数据库查询。

        Args:
            user_id: 用户ID

        Returns:
            用户信息字典,如果用户不存在则返回None

        Example:
            >>> manager = UserManager(db)
            >>> user = manager.get_user(1)
            >>> print(user.get('name'))
            张三
        """

# 先检查缓存
if user_id inself.cache:
            logger.debug(f"从缓存获取用户: {user_id}")
returnself.cache[user_id]

# 从数据库查询
try:
            user = self.db.query_user(user_id)
if user:
NOTE: 缓存查询结果
self.cache[user_id] = user
return user
except Exception as e:
FIXME: 数据库连接池问题
            logger.error(f"查询用户失败: {e}")
returnNone

6.2 函数文档示例

defprocess_user_data(
    user_data: dict,
    validate_email: bool = True,
    normalize_name: bool = True
) -> dict:
"""
    处理用户数据,进行清理和验证。

    对用户数据进行标准化处理,包括姓名规范化、邮箱验证等。

    Args:
        user_data (dict): 包含用户信息的字典
        validate_email (bool, optional): 是否验证邮箱格式,默认True
        normalize_name (bool, optional): 是否规范化姓名,默认True

    Returns:
        dict: 处理后的用户数据

    Raises:
        ValueError: 如果邮箱格式无效

    Examples:
        基本使用:
        >>> data = {"name": " 张三 ", "email": "ZHANG@example.com"}
        >>> result = process_user_data(data)
        >>> print(result["name"])
        张三
        >>> print(result["email"])
        zhang@example.com

        禁用验证:
        >>> data = {"name": "李四", "email": "invalid"}
        >>> result = process_user_data(data, validate_email=False)
        >>> print(result["email"])
        invalid
    """

if normalize_name:
        user_data["name"] = user_data.get("name""").strip()

if validate_email:
        email = user_data.get("email""")
if"@"notin email:
raise ValueError("邮箱格式无效")
        user_data["email"] = email.lower()

return user_data

6.3 类文档示例

classDataProcessor:
"""
    数据处理器,支持多种数据处理操作。

    提供数据的加载、清洗、转换和保存功能。
    支持批处理和大文件处理。

    Attributes:
        source: 数据源路径
        encoding: 文件编码
        chunk_size: 批处理大小

    Example:
        >>> processor = DataProcessor("data.csv", chunk_size=1000)
        >>> processor.load()
        >>> cleaned = processor.clean()
        >>> processor.save("cleaned_data.csv")

    Note:
        大文件处理时使用chunk_size控制内存使用。
    """


def__init__(self, source: str, encoding: str = "utf-8", chunk_size: int = 10000):
"""
        初始化数据处理器。

        Args:
            source: 数据源路径
            encoding: 文件编码
            chunk_size: 批处理大小
        """

self.source = source
self.encoding = encoding
self.chunk_size = chunk_size
self._data = []

defclean(self) -> "DataProcessor":
"""
        清洗数据,返回当前实例支持链式调用。

        Returns:
            DataProcessor: 当前实例

        Example:
            >>> processor = DataProcessor("data.csv")
            >>> processor.clean().transform().save("output.csv")
        """

TODO: 实现数据清洗逻辑
returnself

七、文档字符串工具

7.1 Sphinx

# 安装Sphinx
pip install sphinx

# 生成文档
sphinx-quickstart docs
sphinx-build -b html docs/source docs/build

7.2 pydoc

# 查看模块文档
python -m pydoc module_name

# 生成HTML文档
python -m pydoc -w module_name

7.3 mkdocs

# 安装mkdocs
pip install mkdocs

# 创建文档
mkdocs new myproject
mkdocs serve

八、总结

# 注释规范快速参考

# 1. 单行注释
# 解释代码意图

# 2. 块注释
# 多行注释
# 用于解释复杂逻辑

# 3. 文档字符串
deffunction():
"""函数文档字符串"""
pass

classMyClass:
"""类文档字符串"""
pass

# 4. TODO注释
TODO: 待完成的任务

# 5. FIXME注释
FIXME: 需要修复的问题

# 6. 参数文档
"""
Args:
    param1 (type): 说明
    param2 (type): 说明

Returns:
    type: 说明

Raises:
    Exception: 说明
"""

好的注释和文档字符串是代码质量的重要组成部分。它们帮助其他开发者理解代码的意图和用法,提高代码的可维护性。遵循PEP 8的注释规范,使用清晰、简洁的语言,是写出高质量Python代码的重要环节。配合自动化工具生成文档,可以让代码文档更加专业和易用。