Google Python 风格指南是 Python 社区中最具影响力的代码规范之一,它的目标不仅仅是代码的“外观”,更重要的是提升代码的可读性、一致性和可维护性,正如其开篇所言:“代码被阅读的次数远多于被编写的次数。”

这份指南最初是为 Google 内部使用,但后来公开发布,并被广泛采纳,尤其是在使用 Pylint 等代码检查工具时,其规则是默认的检查标准。
下面我将从几个核心方面,结合具体例子,为你梳理这份指南的精髓。
核心原则
在深入具体规则前,理解其背后的四大核心原则至关重要:
-
可读性优先
(图片来源网络,侵删)- 目标:代码应该是清晰易懂的,像一个好故事一样,逻辑流畅。
- 实践:选择有意义的变量名,避免过度聪明的技巧,保持代码结构简单明了。
-
一致性
- 目标:在一个项目或一个模块中,风格保持一致。
- 实践:遵循项目已有的风格,如果没有,就遵循这份指南,不要在一个文件中混用多种风格。
-
避免“过早优化” (Avoid Premature Optimization)
- 目标:先让代码正确且清晰,然后再考虑性能,除非分析表明是瓶颈,否则不要为了微小的性能提升而牺牲可读性。
- 实践:不要使用那些会让代码难以理解但性能提升微乎其微的“黑魔法”。
-
编写“Pythonic”的代码
- 目标:利用 Python 语言自身的特性,而不是把它写成 C++ 或 Java。
- 实践:多用列表推导式、生成器、装饰器、上下文管理器等 Python 特有的优雅语法。
核心规则详解
代码风格
这是最直观的部分,主要定义了代码的“外貌”。
| 规则项 | Google 风格 | 示例 |
|---|---|---|
| 缩进 | 使用 4 个空格,不要使用制表符。 | python def my_function(): print("Hello") # 4个空格 |
| 行长 | 每行不超过 80 个字符,对于长字符串或注释,可以使用括号进行隐式行连接。 | python # 好的示例 parser = argparse.ArgumentParser( description='Process some integers.') # 不好的示例 parser = argparse.ArgumentParser(description='Process some integers.') |
| 引号 | 优先使用单引号 () 包围字符串,如果字符串本身包含单引号,则使用双引号 ()。 | python s1 = 'This is a string.' s2 = "It's a string with a single quote." |
| 空行 | 顶级函数和类定义前后用两个空行隔开。类内方法定义之间用一个空行隔开,函数内逻辑块之间酌情使用空行。 | python class MyClass: def method_one(self): pass def method_two(self): pass def top_level_function(): pass |
| 空格 | 括号内部不加空格。逗号、分号、冒号前不加空格,后加一个空格。运算符两侧各加一个空格。 | python # 好的示例 spam(ham[1], {eggs: 2}, []) # 不好的示例 spam( ham[ 1 ], { eggs: 2 }, [ ] ) |
命名规范
好的命名是代码可读性的基石。
| 类型 | Google 风格 | 示例 |
|---|---|---|
| 模块名 | 小写字母,单词之间用下划线分隔。 | my_module.py, utils.py |
| 类名 | 使用 CapWords(大驼峰命名法)。 | MyClass, HTTPRequest |
| 异常名 | 类名,但后缀 Error。 |
ValueError, MyCustomError |
| 函数名 | 小写字母,单词之间用下划线分隔。 | my_function(), fetch_data() |
| 方法名 | 同函数名,私有方法以下划线 _ 开头。 |
_internal_method() |
| 变量名 | 小写字母,单词之间用下划线分隔,常量使用全大写加下划线。 | my_variable, TOTAL_COUNT, MAX_OVERFLOW |
| 全局变量 | 尽量避免,必须使用时,使用 g_ 或 gl_ 前缀作为警示。 |
g_current_user |
| 自增/自减计数器 | 在 for 循环中,使用 _ 作为“不关心”的变量名。 |
python for _ in range(10): print("Hello") |
Python 语言特性
这部分是“Pythonic”思想的具体体现。
| 特性 | Google 风格 | 示例 |
|---|---|---|
| 字符串 | 使用 str.format() 或 f-strings (Python 3.6+) 进行字符串插值,不要使用 格式化。 |
python # 好的示例 name = "Alice" print(f"Hello, {name}!") # 不好的示例 print("Hello, %s!" % name) |
| 异常处理 | 优先捕获具体的异常,而不是裸露的 except:,使用 raise 重新抛出异常,并附上上下文信息。 |
python # 好的示例 try: value = int(user_input) except ValueError: logging.error("Invalid integer value: %s", user_input) raise # 不好的示例 try: value = int(user_input) except: logging.error("Something went wrong!") raise |
列表推导式 vs. map()/filter() |
优先使用列表推导式,因为它更清晰、更 Pythonic。 | python # 好的示例 squares = [x**2 for x in range(10)] # 不好的示例 squares = map(lambda x: x**2, range(10)) |
| Lambda 函数 | 保持简短,如果逻辑复杂,应定义一个普通函数。 | python # 好的示例 points.sort(key=lambda p: (p.x, p.y)) # 不好的示例 points.sort(key=lambda p: p.x * 100 + p.y if p.x > 0 else p.y - p.x) |
| 默认参数值 | 可变对象(如列表、字典)绝不能作为默认参数值,这会导致意料之外的行为。 | python # 好的示例 def my_function(a_list=None): if a_list is None: a_list = [] a_list.append(1) return a_list # 不好的示例 def my_function(a_list=[]): a_list.append(1) # 每次调用都会共享同一个列表! return a_list |
| 生成器 | 对于大量数据,优先使用生成器(yield),而不是返回一个完整的列表,以节省内存。 |
python def generate_items(): for i in range(1000000): yield i # 逐个产生,不占用大量内存 |
| 闭包 | 避免在闭包中修改外部变量,如果必须修改,使用 nonlocal 关键字。 |
python def make_counter(): count = 0 def counter(): nonlocal count # 告诉Python我们要修改外层的count count += 1 return count return counter |
| 装饰器 | 广泛用于添加横切关注点,如日志、缓存、权限检查等。 | python @functools.lru_cache(maxsize=128) def get_data_from_api(url): # ... |
其他重要建议
-
文档字符串
- 所有公共模块、函数、类和方法都应有文档字符串。
- 使用 Google 风格的文档字符串,清晰描述“做什么”,而不是“怎么做”。
- 遵循
PEP 257规范。
"""This is a module docstring. This module contains functions for processing data. """ def fetch_data(source_id): """Fetches data from a given source. Args: source_id: The ID of the data source. Returns: A list of data items. Raises: ValueError: If the source_id is invalid. """ # ... return [] -
导入
- 每个导入语句单独一行。
- 按以下顺序分组,每组之间用一个空行隔开:
- 标准库
- 第三方库
- 本地应用/库
- 每组内的模块按字典序排序。
import os import sys import requests from flask import Flask from myproject import utils from myproject.models import User
-
行内注释
- 保持简短,解释代码“为什么这么做”,而不是“做什么”。
- 注释应以 和一个空格开头。
# 好的示例 # We use a special flag to indicate this is a test environment. is_test_env = True # 不好的示例 # Set is_test_env to True is_test_env = True
如何实践
- 阅读官方文档:最权威的来源是 Google Style Guide for Python。
- 使用代码检查工具:
- Pylint:可以检查出指南中绝大部分的风格和逻辑问题,可以直接使用
pylint --generate-rcfile生成一个符合 Google 风格的配置文件。 - Flake8:一个流行的 linter,集成了
pycodestyle(原pep8)、pyflakes和McCabe。 - Black:一个“不妥协”的代码格式化工具,虽然不完全等同于 Google 风格,但它能强制产出统一、可读的代码,是保持一致性的利器。
- Pylint:可以检查出指南中绝大部分的风格和逻辑问题,可以直接使用
- 使用 IDE 插件:大多数现代 IDE(如 VS Code, PyCharm)都支持上述 linter,可以在你编码时实时提示风格问题。
- 团队协作:在团队中统一风格,并将其作为代码审查的一部分。
Google Python 风格指南不仅仅是一套规则,更是一种编程哲学,它鼓励开发者:
- 为读者而写,而非为自己。
- 拥抱语言的优雅,而不是用旧的习惯束缚它。
- 通过纪律和一致性,构建更健壮、更易维护的软件。
遵循这些指南,你的 Python 代码将更具专业水准,也更容易被他人理解和协作。
