注释与编码规范
Python 的注释以 # 开头,从 # 开始到该物理行结束的所有内容都会被解释器忽略。注释可以出现在行首,也可以跟在代码之后,但不能出现在字符串内部——字符串中的 # 就是普通字符。
# 这是整行注释
x = 1 # 这是行尾注释,解释器只处理 x = 1
text = "# 这不是注释" # 引号内的 # 是普通字符
print(text) # 输出: # 这不是注释
注释的实用写法
Python 没有专门的多行注释语法,但可以用连续的单行注释,或利用未赋值的字符串字面值(解释器会将其当作无操作语句执行,但通常不推荐):
# 推荐:连续单行注释
# 计算圆的面积
# 输入:半径 r
# 输出:面积 s
# 不推荐:未赋值字符串虽有效,但可能被某些工具误报
"""
这看起来像注释
但其实是字符串表达式
"""
行尾注释与代码之间应至少留两个空格,这是 PEP 8 的硬性要求:
# 正确
x = x + 1 # 计数器加一
# 错误:空格不足,阅读体验差
x = x + 1 # 计数器加一
注释内容应当解释"为什么"而非"做什么"——代码本身已经说明了做什么:
# 差注释:重复代码语义
x = x + 1 # x 增加 1
# 好注释:解释业务原因
x = x + 1 # 补偿上一步的索引偏移
文档字符串
模块、函数、类和方法的第一条语句如果是字符串字面值,Python 会将其视为文档字符串(docstring),存入对象的 __doc__ 属性,供 help() 和自动化文档工具提取。
def calculate_area(radius):
"""计算圆的面积。
参数:
radius (float): 圆的半径,必须为非负数。
返回:
float: 圆的面积。
示例:
>>> calculate_area(1)
3.141592653589793
"""
import math
return math.pi * radius ** 2
print(calculate_area.__doc__) # 输出文档字符串
文档字符串使用三重引号,即使只有一行也建议用三重引号,以便后续扩展。单行文档字符串的引号与内容之间不留空格:
def noop():
"""Do nothing.""" # 正确
pass
def bad():
""" Do nothing. """ # 错误:多余空格
pass
源文件编码声明
Python 3.12 源码文件默认采用 UTF-8 编码,无需声明即可使用中文、日文、emoji 等字符。但为保证跨平台一致性,可移植代码应限制标识符为 ASCII 字符。
若文件必须使用其他编码(如遗留系统的 Windows-1252),需在文件第一行声明:
# -*- coding: cp1252 -*-
# 此文件使用 Windows-1252 编码保存
city = "São Paulo" # 葡萄牙语字符
如果文件以 shebang 行开头,编码声明必须放在第二行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
print("编码声明在 shebang 之后")
编码声明错误是常见的陷阱。例如,文件实际以 UTF-8 保存却声明为 cp1252,中文字符会被错误解码:
# -*- coding: cp1252 -*-
# 若文件实际包含 UTF-8 编码的中文
name = "中文" # 可能触发 SyntaxError: encoding problem
PEP 8:代码风格指南
PEP 8 是 Python 官方的代码风格指南,核心目标是提高代码的可读性和一致性。它不是语法规则,不遵守不会导致程序报错,但团队协作中应严格执行。
缩进与空白
Python 用缩进表示代码块层级,PEP 8 规定使用 4 个空格,禁止使用 Tab 键。混用空格和 Tab 会导致 TabError:
# 正确:4 空格缩进
def check(value):
if value > 0:
return "positive"
return "non-positive"
# 错误:混用 Tab 和空格
def broken(value):
\tif value > 0: # Tab
return "positive" # 4 空格
# TabError: inconsistent use of tabs and spaces
每行代码最长 79 个字符,文档字符串或注释最长 72 个字符。超过长度应使用括号隐式续行:
# 正确:括号内换行
result = some_function(
first_argument, second_argument,
third_argument)
# 错误:行尾反斜杠续行,脆弱且难读
result = some_function(first_argument, second_argument, \
third_argument)
函数和类之间用两个空行分隔,类的方法之间用一个空行分隔:
class Calculator:
def add(self, a, b):
return a + b
def sub(self, a, b):
return a - b
def helper():
pass
命名约定
PEP 8 定义了四种命名风格,每种对应不同的语义层级:
snake_case(小写加下划线)用于变量、函数和模块名。名称应当见名知意,避免单字母变量(循环索引 i、j、k 除外):
# 正确
user_name = "Alice"
def calculate_total(price, tax):
return price * (1 + tax)
# 错误
n = "Alice" # n 是什么?
def calc(p, t): # 缩写过度
return p * (1 + t)
PascalCase(大写驼峰)用于类名:
class DataProcessor:
pass
class HttpResponse:
pass
UPPER_SNAKE_CASE(全大写加下划线)用于常量:
MAX_CONNECTIONS = 100
DEFAULT_TIMEOUT = 30.0
PI = 3.141592653589793
_leading_underscore(单前导下划线)表示"内部使用"的弱私有约定,不会阻止外部访问,但提示调用者不应直接依赖:
class Buffer:
def __init__(self):
self._data = [] # 内部状态,不建议外部直接修改
def append(self, item):
self._data.append(item)
__double_leading_underscore(双前导下划线)触发名称改写(name mangling),用于避免子类意外覆盖:
class Base:
def __init__(self):
self.__secret = 42 # 被改写为 _Base__secret
class Derived(Base):
def __init__(self):
super().__init__()
self.__secret = 99 # 被改写为 _Derived__secret,不会冲突
b = Base()
print(b._Base__secret) # 42,通过改写后的名称仍可访问
导入规范
导入应分行书写,避免一行导入多个模块。标准库、第三方库、本地模块之间用空行分隔:
# 正确
import os
import sys
import requests
from myproject import utils
# 错误:一行导入多个
import os, sys
# 错误:通配导入,污染命名空间
from os import *
from module import * 应当避免,因为它会导入模块中所有不以下划线开头的名称,可能覆盖现有变量且难以追踪来源。如果模块设计了 __all__ 列表,通配导入会受限制,但仍不推荐在生产代码中使用。
运算符与表达式空格
赋值运算符、比较运算符两侧应各留一个空格,但关键字参数和默认参数值的 = 两侧不留空格:
# 正确
x = 1
y = x + 2
if x == y:
pass
def connect(timeout=30): # 默认参数值不留空格
pass
# 错误
x=1
y = x+2
括号内侧不留空格,逗号后留一个空格:
# 正确
spam(ham[1], {eggs: 2})
# 错误
spam( ham[ 1 ], { eggs: 2 } )
常见风格错误与修正
初学者常犯的错误包括:混用 Tab 和空格、行尾缺少空格、注释与代码对齐不一致、命名风格混乱。以下是一个综合修正示例:
# 修正前:风格混乱
def calc(a,b):
\t#this adds
\treturn a+b
# 修正后:符合 PEP 8
def calculate_sum(first, second):
"""返回两数之和。"""
return first + second
编码规范和注释不是束缚,而是让代码在数月后仍能被自己读懂的保险。养成在保存文件前检查风格的习惯,配合编辑器插件(如 VS Code 的 Python 扩展或 flake8 工具),可以在编码阶段就消灭大部分风格问题。