Python 教程 09:Python 编码规范(PEP 8)
“代码的阅读次数远远多于编写次数。”
PEP 8 是 Python 官方的编码规范,定义了如何写出"Pythonic"的代码。遵循这些规范,你的代码会更专业、更易读、更容易被其他 Python 程序员理解。
1. 什么是 PEP 8
PEP (Python Enhancement Proposal) 是 Python 增强提案。PEP 8 专门定义了 Python 代码的风格指南。
核心思想:
- 代码更多是被阅读,而不是被编写
- 一致性很重要
- 可读性至上
完整文档:https://peps.python.org/pep-0008/
2. 缩进和空格
使用 4 个空格缩进
# 正确
def hello():
print("Hello")
if True:
print("World")
# 错误:使用Tab或2个空格
def hello():
print("Hello") # 2个空格,不推荐
续行对齐
# 方法1:对齐左括号
result = some_function(argument1, argument2,
argument3, argument4)
# 方法2:悬挂缩进
result = some_function(
argument1, argument2,
argument3, argument4
)
# 列表、字典的续行
my_list = [
1, 2, 3,
4, 5, 6,
] # 末尾逗号是好习惯
3. 空行
类和函数之间
# 顶层函数和类之间空2行
def function1():
pass
def function2():
pass
class MyClass:
pass
class AnotherClass:
pass
方法之间
class MyClass:
# 类中的方法之间空1行
def method1(self):
pass
def method2(self):
pass
函数内部逻辑分组
def complex_function():
# 初始化部分
x = 10
y = 20
# 计算部分
result = x + y
# 返回结果
return result
4. 最大行长度
每行不超过 79 个字符(文档字符串/注释不超过 72 个字符)。
# 过长的行需要换行
with open('/path/to/some/file/you/want/to/read') as file_1, \
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())
# 使用括号自然换行(推荐)
result = (some_variable + another_variable
- yet_another_variable)
为什么 79 个字符:
- 传统终端宽度是 80 字符
- 方便并排查看两个文件
- 强制你写简洁的代码
5. 导入
导入顺序
# 1. 标准库
import os
import sys
# 2. 第三方库
import requests
import numpy as np
# 3. 本地模块
from myproject import mymodule
导入规范
# 正确:每次导入一个模块
import os
import sys
# 不推荐:一行导入多个
import os, sys
# 正确:from导入可以一行多个
from subprocess import Popen, PIPE
# 避免通配符导入
# from module import * # 不推荐
6. 命名约定
变量和函数
# 小写,单词用下划线分隔(snake_case)
user_name = "Alice"
total_count = 100
def calculate_sum(numbers):
return sum(numbers)
常量
# 全大写,单词用下划线分隔
MAX_SIZE = 100
DEFAULT_TIMEOUT = 30
PI = 3.14159
类名
# 首字母大写的驼峰命名(PascalCase)
class UserManager:
pass
class HTTPConnection:
pass
私有变量和方法
class MyClass:
def __init__(self):
self.public_var = "公开"
self._protected_var = "受保护"
self.__private_var = "私有"
def public_method(self):
pass
def _protected_method(self):
pass
def __private_method(self):
pass
- 单下划线
_:受保护(约定) - 双下划线
__:私有(名称改编)
7. 表达式和语句
比较
# 正确
if x is None:
pass
if x is not None:
pass
# 不要用==比较None
# if x == None: # 不推荐
# 布尔值比较
if is_valid: # 正确
pass
# if is_valid == True: # 不推荐
字符串
# 使用is检查空字符串
if not my_string: # 推荐
pass
# if my_string == "": # 不推荐
# 字符串拼接
# 少量拼接用+
name = "Hello" + " " + "World"
# 大量拼接用join
words = ["Hello", "World", "Python"]
sentence = " ".join(words)
lambda 函数
# 简单的用lambda
square = lambda x: x ** 2
# 复杂的用def
def complex_function(x):
result = x ** 2
result += 10
return result
8. 注释
行注释
# 注释应该完整的句子,首字母大写
x = 5 # 这是一个解释性注释
# 注释要和代码保持同步
# 过时的注释比没有注释更糟糕
文档字符串
def calculate_area(radius):
"""
计算圆的面积。
Args:
radius (float): 圆的半径
Returns:
float: 圆的面积
Examples:
>>> calculate_area(5)
78.53975
"""
return 3.14159 * radius ** 2
class Calculator:
"""
简单的计算器类。
提供基本的数学运算功能。
"""
def add(self, a, b):
"""返回两数之和。"""
return a + b
9. 编程建议
使用 is 比较单例
# 正确
if x is None:
pass
if x is not None:
pass
# 错误
# if x == None:
异常处理要具体
# 好
try:
value = int(user_input)
except ValueError:
print("无效的数字")
# 不好:捕获所有异常
# try:
# value = int(user_input)
# except: # 太宽泛
# pass
使用 with 处理资源
# 好
with open('file.txt') as f:
data = f.read()
# 不好
# f = open('file.txt')
# data = f.read()
# f.close() # 可能忘记关闭
字符串前缀
# 保持一致的引号风格
name = "Alice" # 或 'Alice'
# 原始字符串
path = r"C:\Users\name"
# f-string
message = f"Hello, {name}"
10. 工具推荐
检查工具
# pylint:全面的代码检查
pylint myfile.py
# flake8:轻量级检查
flake8 myfile.py
# pycodestyle:专门检查PEP 8
pycodestyle myfile.py
格式化工具
# black:自动格式化(最推荐)
black myfile.py
# autopep8:自动修复PEP 8问题
autopep8 --in-place myfile.py
编辑器配置
在 VS Code 中安装 Python 扩展,会自动提示 PEP 8 违规。
11. 何时打破规则
PEP 8 也说了:愚蠢的一致性是头脑简单的妖怪。
可以打破规则的情况:
- 遵循规则会降低可读性
- 与周围代码保持一致(即使它违反 PEP 8)
- 代码是在 PEP 8 之前写的
- 兼容性需要
12. 小结
PEP 8 的核心要点:
- 缩进:4 个空格
- 空行:函数间 2 行,方法间 1 行
- 行长:不超过 79 字符
- 导入:标准库、第三方、本地
- 命名:snake_case(变量/函数)、PascalCase(类)、UPPER_CASE(常量)
- 注释:清晰、同步、文档字符串
- 工具:使用 black、pylint 自动化
遵循 PEP 8 不仅是写出好代码,更是展示专业素养,方便团队协作。
练习题:
- 安装并运行
flake8检查你之前写的代码 - 重构一段不符合 PEP 8 的代码,使其符合规范
- 为你写过的函数添加完整的文档字符串
思考题:
为什么 Python 社区如此重视代码风格的一致性?这对开源项目有什么好处?
本文代码示例: