news 2026/7/23 21:19:11

Google Python 代码注释与文档字符串风格完全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Google Python 代码注释与文档字符串风格完全指南

本文基于 Google 官方 Python 风格指南,系统梳理 Python 代码中注释、文档字符串、TODO 的完整规范,包含正反示例与最佳实践,可作为团队代码规范与个人知识库归档。

一、为什么需要统一的注释风格

注释是代码可读性的核心保障。好的注释不描述代码本身在做什么,而是解释为什么这么做、业务意图、边界条件、潜在坑点。统一的注释风格能让团队成员快速读懂彼此的代码,降低维护成本。

Google Python 风格指南对注释的核心原则:

  • 文档字符串(Docstring):对外说明「怎么用」,写给调用者看
  • 行内注释(Inline Comment):对内说明「为什么」,写给维护者看
  • 不做代码翻译:假设读者懂 Python,不需要解释基础语法

二、文档字符串(Docstrings)基础规范

2.1 基本格式

Python 使用三双引号"""作为文档字符串标准格式(遵循 PEP 257),禁止使用三单引号'''

结构要求

  1. 第一行是一句话摘要,不超过 80 字符,以句号、问号或感叹号结尾;
  2. 如果内容更多,空一行后续写详细说明;
  3. 详细内容与开头引号保持相同缩进位置。

2.2 正反示例

✅ 正确:

python

运行

def fetch_data(key: str) -> dict: """Fetches data from cache by key. Retrieves cached data for the given key. Returns an empty dict if the key does not exist. """

❌ 错误:

python

运行

def fetch_data(key: str) -> dict: # 错误:使用单引号 '''Fetches data.''' def fetch_data(key: str) -> dict: """ 错误:首行就换行,没有摘要行 Fetches data from cache. """

三、模块级文档字符串

3.1 规范要求

每个 Python 文件开头,在导入语句之前,必须有模块级文档字符串,描述文件的整体内容、用途、导出的类和函数、使用示例

文件开头还应包含项目对应的许可证声明。

3.2 标准模板

python

运行

"""A one-line summary of the module or program, terminated by a period. Leave one blank line. The rest of this docstring should contain an overall description of the module or program. Optionally, it may also contain a brief description of exported classes and functions and/or usage examples. Typical usage example: foo = ClassFoo() bar = foo.function_bar() """

3.3 测试模块的特殊说明

测试文件的模块文档字符串不是必需的。只有当存在额外信息时才添加,例如:

  • 测试的特殊运行方式
  • 不寻常的初始化模式
  • 对外部环境的依赖

✅ 测试模块示例:

python

运行

"""This blaze test uses golden files. You can update those files by running `blaze run //foo/bar:foo_test -- --update_golden_files` from the `google3` directory. """

❌ 无意义的文档字符串不要写:

python

运行

"""Tests for foo.bar.""" # 没有提供任何新信息,禁止使用

四、函数与方法文档字符串

4.1 什么时候必须写文档字符串

满足以下任一条件的函数,强制要求文档字符串:

  • 属于公开 API
  • 函数体有一定规模
  • 逻辑不直观、非显而易见

4.2 核心原则

文档字符串要让读者不看函数实现代码就能正确调用。描述调用语法和语义,不描述实现细节;但如果实现细节会影响使用(比如副作用),必须注明。

4.3 标准三段式结构

Args:参数说明

逐个列出参数名,冒号后接描述。如果代码没有类型注解,描述中必须包含类型。

  • *args**kwargs也要列出。
Returns:返回值说明

描述返回值的语义和类型。如果函数只返回None,可以省略此节。

  • 生成器函数用Yields:而不是Returns:
Raises:异常说明

列出所有与接口相关的异常及描述。不要列出因 API 误用而抛出的异常(比如参数校验错误),因为那不属于接口契约的一部分。

4.4 完整标准示例

python

运行

def fetch_smalltable_rows( table_handle: smalltable.Table, keys: Sequence[bytes | str], require_all_keys: bool = False, ) -> Mapping[bytes, tuple[str, ...]]: """Fetches rows from a Smalltable. Retrieves rows pertaining to the given keys from the Table instance represented by table_handle. String keys will be UTF-8 encoded. Args: table_handle: An open smalltable.Table instance. keys: A sequence of strings representing the key of each table row to fetch. String keys will be UTF-8 encoded. require_all_keys: If True only rows with values set for all keys will be returned. Returns: A dict mapping keys to the corresponding table row data fetched. Each row is represented as a tuple of strings. For example: {b'Serak': ('Rigel VII', 'Preparer'), b'Zim': ('Irk', 'Invader'), b'Lrrr': ('Omicron Persei 8', 'Emperor')} Returned keys are always bytes. If a key from the keys argument is missing from the dictionary, then that row was not found in the table (and require_all_keys must have been False). Raises: IOError: An error occurred accessing the smalltable. """

4.5 重写方法的特殊规则

子类重写父类方法时:

  • 如果加了@override装饰器,且重写没有改变语义,可以不写文档字符串;
  • 如果重写后语义有变化、增加了副作用,必须写文档字符串说明差异;
  • """See base class."""也是允许的,但@override本身就足够说明文档在父类。

✅ 正确示例:

python

运行

from typing_extensions import override class Child(Parent): @override def do_something(self): pass # 有 @override,可以不写文档字符串

五、类文档字符串

5.1 规范要求

类定义下方必须有文档字符串,描述类的用途。公开属性(不包括 property)需要在Attributes:节中列出,格式与函数的Args:一致。

5.2 标准示例

python

运行

class SampleClass: """Summary of class here. Longer class information... Longer class information... Attributes: likes_spam: A boolean indicating if we like SPAM or not. eggs: An integer count of the eggs we have laid. """ def __init__(self, likes_spam: bool = False): """Initializes the instance based on spam preference. Args: likes_spam: Defines if instance exhibits this preference. """ self.likes_spam = likes_spam self.eggs = 0

5.3 异常类命名与文档

异常类的文档字符串应该描述异常本身代表什么,而不是在什么上下文抛出。

✅ 正确:

python

运行

class OutOfCheeseError(Exception): """No more cheese is available."""

❌ 错误:

python

运行

class OutOfCheeseError(Exception): """Raised when no more cheese is available.""" # 冗余表述

六、块注释与行内注释

6.1 使用场景

  • 复杂操作:在操作前写几行块注释说明整体思路;
  • 不直观的技巧:在行尾加行内注释解释;
  • 代码评审时需要解释的逻辑,现在就写注释。

6.2 格式要求

  • 行内注释与代码之间至少间隔 2 个空格;
  • #号后至少跟 1 个空格再写注释文字;
  • 绝对不要描述代码本身在做什么,假设读者懂 Python。

✅ 正确示例:

python

运行

# We use a weighted dictionary search to find out where i is in # the array. We extrapolate position based on the largest num # in the array and the array size and then do binary search to # get the exact number. if i & (i - 1) == 0: # True if i is 0 or a power of 2. process(i)

❌ 反面典型(废话注释):

python

运行

# BAD: Now go through the b array and make sure whenever i occurs # the next element is i+1

这种注释只是把代码翻译成了人话,没有任何信息增量,反而增加阅读负担。


七、标点、拼写与语法

7.1 基本要求

  • 注释要像叙述文本一样可读,正确使用大小写和标点;
  • 完整句子比句子片段更易读;
  • 行尾短注释可以非正式,但全篇风格要保持一致;
  • 注意拼写和语法,避免低级错误。

7.2 为什么如此重要

虽然标点和拼写看似小事,但源代码的清晰度和可读性对长期维护至关重要。规范的注释能显著降低团队沟通成本和新人上手成本。


八、TODO 注释规范

8.1 什么时候用 TODO

用于临时方案、短期解决方案、「够用但不完美」的代码。

8.2 标准格式

plaintext

# TODO: 引用链接 - 说明文字
  • TODO全大写,后面跟冒号;
  • 冒号后是上下文引用(最好是 bug 链接,而不是人名);
  • 然后用连字符-引出说明文字。

✅ 正确:

python

运行

# TODO: crbug.com/192795 - Investigate cpufreq optimizations.

❌ 不推荐的旧写法:

python

运行

# TODO(crbug.com/192795): Investigate cpufreq optimizations. # TODO(yourusername): Use a "*" here for concatenation operator.

8.3 禁止事项

  • 不要用个人用户名作为 TODO 的上下文;
  • TODO 要可追溯、可跟进,指向 issue 或 bug 最佳;
  • 如果写「将来某天做某事」,务必给出具体日期或具体触发事件。

九、日志与错误消息中的文字规范

9.1 日志字符串规范

日志函数第一个参数用字符串字面量,不要用 f-string。原因:

  • 部分日志实现会将原始模式字符串作为可查询字段;
  • 避免为未启用的日志级别浪费渲染时间。

✅ 正确:

python

运行

logging.info('Current $PAGER is: %s', os.getenv('PAGER', default=''))

❌ 错误:

python

运行

logging.info(f'Cannot write to home directory, $HOME={homedir!r}')

9.2 错误消息三原则

异常信息、用户提示必须满足:

  1. 消息必须精确匹配实际错误情况;
  2. 插入的变量内容要清晰可识别;
  3. 便于自动化处理(比如 grep 检索)。

✅ 正确:

python

运行

if not 0 <= p <= 1: raise ValueError(f'Not a probability: {p=}')

❌ 反面示例:

python

运行

try: os.rmdir(workdir) except OSError: # 问题:想当然认为是目录已删除,实际可能因为其他原因失败 logging.warning('Directory already was deleted: %s', workdir)

十、核心原则总结

10.1 文档字符串 vs 行内注释

表格

类型受众内容重点位置
文档字符串调用者 / 使用者怎么用、入参出参、异常函数 / 类 / 模块开头
行内注释维护者 / 阅读者为什么这么做、坑点、技巧代码旁 / 行尾

10.2 五条黄金法则

  1. 不翻译代码:不说「这行在循环」,说「为什么要循环、循环解决什么问题」;
  2. 公开 API 必有文档字符串:别人不看你源码就能用;
  3. 参数、返回值、异常三段式:结构统一,快速检索;
  4. TODO 可追溯:挂 issue 链接,不写人名;
  5. 保持一致性:局部风格比全局规范更重要,与周边代码风格统一。

10.3 最后的话

BE CONSISTENT. 风格指南的意义是让大家拥有共同的编码词汇,从而专注于表达内容,而非表达方式。

如果你修改已有代码,先花几分钟观察周边代码的风格。如果周围用_idx后缀,你也用;如果注释有特殊格式,你也保持一致。局部一致性的优先级甚至高于全局规范 —— 突兀的风格差异会打断读者的阅读节奏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 21:18:02

做知识付费/有声书用什么配音软件?2026年长文本TTS批量生成实测

做知识付费/有声书用什么配音软件&#xff1f;2026年长文本TTS批量生成实测 核心结论&#xff1a;如果你跟我一样在做线上课或有声书&#xff0c;千万别用那些只能粘几千字的小工具。批量处理能力和SSML长文本稳定性是第一指标。实测下来&#xff0c;fuym.cn 浮云梦配音&#…

作者头像 李华
网站建设 2026/7/23 21:14:55

TMS320C6424 DSP启动配置与系统初始化实战指南

1. 项目概述与核心价值 在嵌入式DSP系统的开发中&#xff0c;最让人头疼的往往不是算法实现&#xff0c;而是系统上电后“第一脚”怎么迈出去。我见过不少项目&#xff0c;代码写得漂亮&#xff0c;硬件设计也没问题&#xff0c;但一上电就是一片死寂&#xff0c;或者跑起来后外…

作者头像 李华
网站建设 2026/7/23 21:13:35

AI建站工具从0到1全流程攻略:零代码实现智能对话网站

AI建站工具从0到1全流程攻略&#xff1a;零代码实现智能对话网站很多人在面对“AI建站工具”这个概念时&#xff0c;第一反应往往是&#xff1a;这到底是个什么神器&#xff1f;和传统网站搭建有什么本质区别&#xff1f;简单来说&#xff0c;传统建站你需要懂点代码&#xff0…

作者头像 李华
网站建设 2026/7/23 21:09:12

【愚公系列】《Android应用案例开发大全》002-Android 开发环境的搭建

&#x1f48e;【行业认证权威头衔】 ✔ 华为云天团核心成员&#xff1a;特约编辑/云享专家/开发者专家/产品云测专家 ✔ 开发者社区全满贯&#xff1a;CSDN博客&商业化双料专家/阿里云签约作者/腾讯云内容共创官/掘金&亚马逊&51CTO顶级博主 ✔ 技术生态共建先锋&am…

作者头像 李华
网站建设 2026/7/23 21:04:57

AM6x MPU GPIO配置实战:从硬件架构到电机控制与传感器采集

1. 项目概述&#xff1a;为什么GPIO是嵌入式开发的基石 在嵌入式系统开发中&#xff0c;无论你是做工业控制、智能家居还是消费电子&#xff0c;有一个模块你几乎无法绕过&#xff0c;那就是通用输入输出接口&#xff0c;也就是我们常说的GPIO。它就像是处理器的“手脚”和“感…

作者头像 李华