Python 注释和文档字符串
最后修改于 2025 年 4 月 2 日
注释和文档字符串对于记录 Python 代码至关重要。注释用于解释实现细节,而文档字符串则描述用法和功能。本指南涵盖了从基本语法到文档生成的所有方面。正确的文档可以提高代码的可维护性,并启用自动生成文档的工具。学习如何遵循 Python 最佳实践来编写清晰有效的注释和文档字符串。
单行注释
单行注释以 # 符号开头,并一直持续到行尾。它们用于简短的解释和行内注释。此示例展示了正确的单行注释用法。有效的注释解释的是“为什么”,而不是“是什么”——代码本身就显示了正在做什么。
# Calculate circle area (single-line comment before code)
def circle_area(radius):
return 3.14159 * radius ** 2 # Using approximate value of π
# Bad example: Redundant comment
x = x + 1 # Increment x by 1
# Good example: Explains non-obvious logic
# Adjust for edge case when divisor is near zero
if abs(divisor) < 1e-10:
result = float('inf')
# Additional example: Commented-out code (use sparingly)
# old_value = calculate_old_way() # Deprecated 2024-01-15
new_value = calculate_new_way()
# Additional example: End-of-line comments
names = ["Alice", "Bob", "Charlie"] # List of user names
第一个注释解释了函数的作用,而行内注释则说明了 π 的近似值。避免冗余的注释,这些注释只是重复代码明显做了什么。相反,请记录非显而易见实现的根本原因。
通常应删除被注释掉的代码(请使用版本控制),但当暂时保留时,请包含弃用说明。行尾注释应简短,并且仅在真正有助于理解该特定行时使用。
多行注释
Python 没有真正的多行注释语法,但可以使用连续的单行注释或三引号字符串进行较长的解释。此示例展示了这两种方法。多行解释对于复杂的算法或模块级文档非常有用。
"""
This is technically a string, not a comment,
but often used for module-level documentation.
It can span multiple lines and is ignored when
not assigned to a variable.
"""
# This is the preferred way for actual comments
# that span multiple lines in Python. Each line
# starts with a # and the comment is clearly
# distinguished from docstrings.
def complex_algorithm(data):
# Phase 1: Data preprocessing
# - Normalize input values
# - Handle missing data
# - Convert categorical variables
# Phase 2: Core calculation
# Uses the Smith-Waterman algorithm
# with custom modifications for our use case
pass
# Additional example: Block comment before code
###########################################
# Database Connection Handler #
# Manages connection pooling and retries #
###########################################
class DatabaseHandler:
pass
顶部的三引号字符串实际上是一个字符串字面量,但当它未赋值给变量时,它就像注释一样工作。对于实际的多行注释,首选连续的单行注释,因为它们是明确的注释。
complex_algorithm 函数展示了如何构建关于多阶段过程的详细解释。分节标题(如数据库处理器的示例)可以谨慎使用时帮助组织大型代码文件。
函数文档字符串
文档字符串是出现在模块、函数、类和方法中的第一个语句的字符串字面量。它们遵循 PEP 257 约定,并描述对象的作用和用法。此示例演示了正确的函数文档字符串格式。良好的文档字符串可以启用自动生成文档,并帮助 help() 和 IDE 等工具。
def calculate_interest(principal, rate, years):
"""Calculate compound interest.
Args:
principal (float): Initial investment amount
rate (float): Annual interest rate (e.g., 0.05 for 5%)
years (int): Investment period in years
Returns:
float: Final amount after compound interest
Examples:
>>> calculate_interest(1000, 0.05, 10)
1628.894626777442
"""
return principal * (1 + rate) ** years
# Additional example: One-line docstring
def greet(name):
"""Return a greeting string for the given name."""
return f"Hello, {name}!"
# Additional example: Multi-class function
def process_data(data, verbose=False):
"""Process input data with optional verbosity.
Performs data cleaning, normalization, and feature extraction
in a single pipeline.
Parameters:
data (DataFrame): Input dataset
verbose (bool): If True, print progress messages
Raises:
ValueError: If data contains invalid values
Note:
This function modifies the input DataFrame in place.
"""
# Implementation here
pass
calculate_interest 文档字符串遵循流行的 Google 风格,具有清晰的参数、返回值和示例部分。单行文档字符串适用于简单的函数。多类函数值得更详细的文档字符串,涵盖所有参数、返回值、异常和特殊注释。
文档字符串应侧重于函数的作用(其接口),而不是其工作原理(实现)。它们成为函数 __doc__ 属性的一部分,并且可以通过 help() 访问。
类文档字符串
类文档字符串描述类的作用、属性和使用模式。它们出现在类定义之后、方法定义之前。此示例展示了全面的类文档。文档完善的类更容易使用和维护。
class BankAccount:
"""A class representing a basic bank account.
Attributes:
account_number (str): Unique account identifier
balance (float): Current account balance
owner (str): Account holder's name
"""
def __init__(self, account_number, owner, balance=0.0):
"""Initialize a new bank account.
Args:
account_number (str): Account identifier
owner (str): Account holder name
balance (float, optional): Initial balance. Defaults to 0.0.
"""
self.account_number = account_number
self.owner = owner
self.balance = balance
# Additional example: Detailed class with methods
class Vector:
"""A mathematical vector in 2D space.
Supports basic vector operations: addition, scalar multiplication,
dot product, and magnitude calculation.
Examples:
>>> v1 = Vector(1, 2)
>>> v2 = Vector(3, 4)
>>> v1 + v2
Vector(4, 6)
"""
def __init__(self, x, y):
self.x = x
self.y = y
def magnitude(self):
"""Calculate the vector's magnitude.
Returns:
float: The vector's length
"""
return (self.x**2 + self.y**2)**0.5
BankAccount 文档字符串描述了类的作用并列出了其属性。Vector 类展示了更详细的文档,包括使用示例。类文档字符串应提供足够的信息,以便用户在不阅读其实现的情况下使用该类。
类中的方法文档字符串遵循与函数文档字符串相同的原则。magnitude 方法演示了一个简单而清晰的文档字符串。总的来说,这些构成了全面的类文档。
模块文档字符串
模块文档字符串出现在 Python 文件的顶部,描述模块的作用、内容和用法。它们应该是任何导入或代码之前的三个引号字符串。此示例展示了一个正确记录的模块。模块文档字符串帮助用户理解文件在整个系统中的作用。
"""Financial calculations module.
Provides functions for common financial calculations including
interest, annuities, and investment returns.
Example:
>>> from financial import calculate_interest
>>> calculate_interest(1000, 0.05, 10)
1628.894626777442
Copyright (c) 2025 Financial Tools Inc.
License: MIT
"""
import math
from datetime import date
# Additional example: Detailed module docstring
"""Image processing utilities.
This module contains functions for common image manipulation tasks:
- Color space conversions
- Filter applications
- Feature detection
- Image I/O operations
The implementation uses NumPy for efficient array operations and
supports both RGB and grayscale images.
Note:
For advanced computer vision tasks, consider using OpenCV
instead of these basic functions.
"""
financial 模块文档字符串描述了其作用、内容,并包含一个快速示例。版权和许可信息通常出现在模块文档字符串中。图像处理示例显示了更详细的文档,包括实现说明和建议。
模块文档字符串应足够全面,以便用户无需阅读所有代码即可了解模块提供的功能。它们成为模块的 __doc__ 属性,并被文档生成器使用。
文档字符串格式
Python 中存在几种文档字符串格式,每种都有其约定。最常见的是 Google 风格、NumPy/SciPy 风格和 reStructuredText。此示例比较了这些格式。一致的文档字符串风格提高了代码库的可读性。
# Google Style
def google_style(a, b):
"""Compute the sum of two numbers.
Args:
a (int or float): First operand
b (int or float): Second operand
Returns:
int or float: Sum of a and b
Examples:
>>> google_style(2, 3)
5
"""
return a + b
# NumPy/SciPy Style
def numpy_style(a, b):
"""Compute the sum of two numbers.
Parameters
----------
a : int or float
First operand
b : int or float
Second operand
Returns
-------
int or float
Sum of a and b
Examples
--------
>>> numpy_style(2, 3)
5
"""
return a + b
# reStructuredText Style
def rst_style(a, b):
"""Compute the sum of two numbers.
:param a: First operand
:type a: int or float
:param b: Second operand
:type b: int or float
:return: Sum of a and b
:rtype: int or float
:example:
>>> rst_style(2, 3)
5
"""
return a + b
Google 风格简洁易读,在通用 Python 代码中很受欢迎。NumPy 风格使用带有下划线的节标题,在科学 Python 中很常见。reStructuredText 更为冗长,但与 Sphinx 文档工具配合效果很好。这三种格式都是有效的——关键是在项目内保持一致。
每种格式都包含相同基本信息:参数、返回值和示例。根据项目的约定和文档工具进行选择。许多 IDE 可以以您喜欢的格式生成文档字符串存根。
文档生成
可以使用 Sphinx、pdoc 和 mkdocs 等工具将 Python 文档字符串自动转换为文档。此示例显示了为 Sphinx 格式化的文档字符串。正确格式化的文档字符串可以毫不费力地生成专业文档。
def sphinx_ready(a, b):
"""Compute the product of two numbers.
This function multiplies two numbers with proper type checking.
It serves as an example of Sphinx-compatible docstrings.
:param a: First factor
:type a: int or float
:param b: Second factor
:type b: int or float
:return: Product of a and b
:rtype: int or float
:raises TypeError: If either argument isn't numeric
.. note::
This function doesn't handle complex numbers.
.. warning::
Floating-point multiplication may have precision issues.
Example:
.. code-block:: python
result = sphinx_ready(3, 4)
print(result) # 12
"""
if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
raise TypeError("Numeric arguments required")
return a * b
Sphinx 文档字符串使用 reStructuredText 语法,并带有 .. note:: 和 .. warning:: 等特殊指令。:param:、:type:、:return: 和 :raises: 标签创建结构化文档。代码示例使用 .. code-block:: 指令。
当由 Sphinx 处理时,这些文档字符串会生成格式精美的 HTML/PDF 文档,并带有适当的交叉引用。许多开源 Python 项目都采用这种方法来创建其官方文档。
最佳实践
为所有公共模块、函数、类和方法编写文档字符串。在代码更改时,请保持注释和文档字符串的最新状态。使用文档字符串记录接口(是什么),使用注释解释实现(如何)。遵循 PEP 8 和 PEP 257 风格指南。选择一种文档字符串格式,并在整个项目保持一致。
资料来源
从以下资源了解更多信息:PEP 257 文档字符串约定、Google Python 风格指南 和 Sphinx 文档。
作者
我的名字是 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。
列出所有 Python 教程。