第03章 Python 教程-基础语法:注释与变量

第3章 基础语法:注释与变量

本章介绍编写 Python 代码时的基础规则,包括注释与文档字符串的写法与作用,变量的创建、重新赋值、多变量赋值与解包,以及标识符的命名规则与常量约定;最后梳理 PEP 8 代码规范中缩进、空格、行长与空行等常见要求。这些书写与命名习惯会贯穿后续所有章节。

3.1 代码注释与文档字符串

3.1.1 注释的作用

注释是写给代码阅读者的说明,Python 解释器不会执行注释中的内容。合理使用注释可以:

  • 说明代码的目的、业务规则或实现原因;
  • 记录参数、边界条件和注意事项;
  • 暂时屏蔽一小段代码,辅助调试;
  • 帮助自己和其他开发者快速理解程序。

注释应重点解释"为什么这样做",而不是机械复述代码已经清楚表达的内容。

3.1.2 单行注释的两种写法

Python 使用 # 表示注释。从 # 开始到当前物理行末尾的内容都不会执行,常见写法分为以下两种。

方式一:使用独占一行的单行注释

注释单独占一行,通常放在相关代码的上方,用于说明接下来一段代码的目的、原因或注意事项;独占一行的注释应与所说明的代码保持相同缩进,并在 # 后留一个空格:

复制代码
# 计算圆的面积
radius = 3
area = 3.14159 * radius**2
print(area)

方式二:使用行尾注释

行尾注释放在代码右侧,适合补充简短且与当前语句直接相关的信息;按照 PEP 8 的常见写法,代码与行尾注释之间至少留两个空格,# 后留一个空格。行尾注释应尽量简短,说明较长时应改用独占一行的注释:

复制代码
MAX_RETRY_COUNT = 3  # 外部服务偶尔超时,最多重试 3 次
print("程序结束", end="")  # 输出结束后不换行

无论采用哪种方式,都不要为每条简单语句添加无意义的注释。注释应提供代码本身没有直接表达的信息:

复制代码
# 推荐:说明代码背后的业务原因
retry_count = 3  # 外部服务偶尔超时,最多重试 3 次

# 不推荐:只是重复代码含义
nickname = "阿明"  # 把阿明赋值给 nickname

3.1.3 多行说明与文档字符串

Python 没有专门的"多行注释"语法。需要编写多行说明时,可以根据用途选择以下两种方式。

方式一:使用连续的单行注释

普通的多行代码说明应让每一行分别以 # 开头;这种方式创建的才是真正的注释,适合解释业务规则、实现原因和注意事项。编辑器通常提供批量添加或取消行注释的快捷操作:

复制代码
# 用户名必须由字母、数字或下划线组成,
# 长度应在 3~20 个字符之间,
# 并且不能与已有用户名重复。
username = "python_user"

方式二:使用三引号字符串或文档字符串

三引号用于创建多行字符串;位于模块、类或函数开头时,这个字符串称为文档字符串(docstring),用于说明代码用途。三引号不是真正的多行注释,不建议用它屏蔽代码:

复制代码
# 普通多行字符串
text_block = """第一行
第二行
第三行"""

print(text_block)


# 函数文档字符串
def join_tags(tag_list):
    """把标签列表拼接成顿号分隔的文本。"""
    return "、".join(tag_list)


print(join_tags(["Python", "入门", "笔记"]))
print(join_tags.__doc__)

3.2 变量、赋值与命名规则

3.2.1 变量与对象的关系

在 Python 中,变量是绑定到对象的名称。可以把变量理解为对象的"标签",而不是只能存放某一种数据的固定盒子。

赋值过程

以 name = "Python" 为例,Python 先计算赋值符号右侧的表达式,得到字符串对象 "Python",再将变量名 name 绑定到该对象:

复制代码
name = "Python"

name ─────> "Python"
变量名       字符串对象

此后,程序便可以通过变量名访问对应对象。

动态类型

变量本身不需要声明类型,类型属于变量当前引用的对象。同一个变量可以在程序运行过程中重新绑定到不同类型的对象:

复制代码
item_count = 10
print(f"item_count 的类型:{type(item_count)}")  # <class 'int'>

item_count = "十"
print(f"item_count 的类型:{type(item_count)}")  # <class 'str'>

这种特性称为动态类型。不过在实际项目中,频繁改变同一变量表示的数据类型会降低代码可读性,应尽量让变量的含义保持稳定。

3.2.2 变量的创建、使用与重新赋值

变量的创建、使用和修改遵循以下规则:

  • 变量必须先赋值,才能在表达式中使用;
  • 赋值符号 = 表示将右侧表达式的结果绑定到左侧变量名,并不表示数学中的相等关系;
  • 变量可以重新赋值,重新赋值后,变量名将引用新的对象;
  • 读取尚未定义的变量会触发 NameError。

下面的代码依次演示变量的创建、使用和修改:

复制代码
# 创建变量
unit_price = 12.5
quantity = 4

# 使用变量计算并输出结果
total_price = unit_price * quantity
print(total_price)  # 50.0

# 修改变量并重新计算
unit_price = 15.0
total_price = unit_price * quantity
print(total_price)  # 60.0

# print(undefined_name)  # NameError: name 'undefined_name' is not defined

3.2.3 多变量赋值与解包

Python 支持在一条语句中为多个变量赋值,常见用法如下:

  • 使用链式赋值,可以让多个变量绑定到同一个对象;
  • 使用解包赋值,可以将多个值依次绑定到对应的变量;
  • 解包时左右两侧的元素数量通常必须一致,否则会触发 ValueError;
  • 解包可以直接交换变量,不需要额外的临时变量;
  • 不需要使用某个值时,通常用 _ 接收;_ 仍是普通变量名,只是在编码习惯上表示忽略该值。

下面的代码依次演示这些用法:

复制代码
# 多个变量绑定到同一个对象
x = y = z = 0
print(x, y, z)  # 0 0 0

# 解包赋值
name, age, city = "林晓", 21, "杭州"
print(name, age, city)  # 林晓 21 杭州

# 交换变量
left = 10
right = 20
left, right = right, left
print(left, right)  # 20 10

# 忽略不需要的值
name, _, city = ("李华", 20, "上海")
print(name, city)  # 李华 上海

# 左右两侧数量不一致会触发 ValueError
# first, second = (1, 2, 3)

3.2.4 标识符的语法规则

变量名、函数名、类名和模块名等由开发者命名的名称统称为标识符。Python 标识符需要遵守以下规则:

  • 可以包含 Unicode 字母、数字和下划线;
  • 不能以数字开头;
  • 大小写敏感:name、Name 和 NAME 会被当作三个互不相同的名称;
  • 不能与 Python 关键字相同;
  • 可以先使用 isidentifier() 检查名称形式,再使用 keyword.iskeyword() 排除关键字;
  • 软关键字只在特定语法位置具有特殊含义,可以通过 keyword.softkwlist 查看。

下面的代码依次演示合法与非法标识符、名称检查以及关键字查询:

复制代码
import keyword

# 合法标识符
user_name = "Alice"  # 合法
用户名称 = "张三"    # 合法,但跨团队项目通常优先使用英文名称
name2 = "Bob"        # 合法

# 非法标识符,取消注释后会触发 SyntaxError
# 2name = "Bob"      # 非法:不能以数字开头
# class = "一班"     # 非法:class 是关键字

# 检查候选名称
names = ["user_name", "2name", "class", "用户名称"]

for name in names:
    valid = name.isidentifier() and not keyword.iskeyword(name)
    print(f"{name!r}: {valid}")

# 查看当前版本的关键字和软关键字
print(keyword.kwlist)
print(keyword.softkwlist)

3.2.5 标识符的命名规范

名称除了满足语法规则,还应准确表达用途。PEP 8 中常见的命名约定如下:

对象 推荐风格 示例
变量、函数、方法 小写蛇形命名法 total_price、get_user()
类 大驼峰命名法 UserAccount
常量 全大写蛇形命名法 MAX_RETRY_COUNT
内部使用的名称 单下划线开头 _cache
特殊方法 两侧双下划线,由 Python 预定义 __init__()

命名时还应注意:

  • 选择有含义的名称,避免大量使用 a、b、data1;

  • 不要覆盖 list、str、sum 等内置名称;

  • 单字母 l、大写 O 和大写 I 容易与数字混淆,通常不单独使用;

  • 布尔变量可以使用 is_、has_、can_ 等前缀表达判断含义。

    is_logged_in = True
    has_permission = False
    max_retry_count = 3

3.2.6 常量的命名约定

常量是程序运行期间不希望被修改的值。Python 中的常量主要遵循以下约定:

  • Python 不提供让自定义变量无法重新赋值的语言机制;
  • 通常使用全大写蛇形命名法表示常量,提醒开发者不要修改;
  • Final 类型注解可以向类型检查器表达常量意图,但运行时仍然允许重新赋值;
  • True、False 和 None 是 Python 语言定义的常量,不能作为赋值目标。

下面的代码演示普通常量和带有 Final 类型注解的常量:

复制代码
from typing import Final

# 使用命名约定表示常量
PI = 3.1415926
MAX_CONNECTIONS = 100
DEFAULT_ENCODING = "utf-8"

# 使用 Final 进一步表达常量意图
SECONDS_PER_MINUTE: Final = 60

# 运行时可以重新赋值,但类型检查器会报告问题
# SECONDS_PER_MINUTE = 30

# Python 语言定义的常量不能作为赋值目标
# True = 1  # SyntaxError

3.3 Python 代码规范

代码规范用于统一代码的书写方式,使程序更容易阅读、修改和协作维护。PEP 8 是 Python 官方代码风格指南;实际开发中应优先保持项目内部一致,项目规范与 PEP 8 不同时,以项目规范为准。注释和命名规范已分别在 3.1 节和 3.2 节介绍,本节不再重复。

3.3.1 缩进与代码块

Python 使用缩进划分代码块,缩进不仅影响代码格式,还会直接影响程序结构。主要规则如下:

规则 说明
每级缩进使用 4 个空格 适用于函数、条件语句、循环语句等代码块
优先使用空格缩进 可以将编辑器的 Tab 键设置为插入 4 个空格
不要混用制表符和空格 混用可能触发 TabError 或 IndentationError
同一代码块保持相同缩进 缩进层级不同表示代码所属的结构不同

下面的代码演示如何使用统一缩进表示嵌套的代码块:

复制代码
"""演示使用统一缩进表示代码块。"""

temperature = 30
is_outdoor = True

if temperature >= 30:
    print("天气炎热")
    if is_outdoor:
        print("外出时注意防晒")

print("天气检查完成")

3.3.2 空格与换行

适当的空格和换行可以突出表达式结构,但多余空格会降低可读性。常见规则如下:

使用位置 推荐写法 说明
二元运算符两侧 total = price * quantity 通常在运算符两侧各留一个空格
逗号之后 [1, 2, 3] 逗号前不留空格,逗号后留一个空格
括号内部 sum(numbers) 紧邻括号的内容两侧不添加空格
函数调用之前 print(total) 函数名与左括号之间不添加空格
关键字参数的等号两侧 round(number, ndigits=2) 未使用类型注解时,等号两侧不添加空格
较长的表达式 使用 ()、[] 或 {} 换行 优先使用隐式续行,避免使用反斜杠续行

下面的代码演示常用的空格规则,以及在括号内拆分较长的表达式:

复制代码
"""演示空格和换行的规范写法。"""

unit_price = 20
quantity = 3
shipping_fee = 10
discount_amount = 5

numbers = [1, 2, 3, 4]
total_price = (
    unit_price * quantity
    + shipping_fee
    - discount_amount
)

print(f"数字总和:{sum(numbers)}")
print(f"应付金额:{round(total_price, ndigits=2)}")

3.3.3 行长与空行

合理控制行长可以减少横向滚动,适当使用空行可以划分代码的逻辑层次。PEP 8 的建议如下:

项目 建议
代码行 每行最多 79 个字符
注释和文档字符串 连续文本每行最多 72 个字符
顶层函数和类 定义之间空两行
类中的方法 定义之间空一行
函数内部 可以使用少量空行划分不同的处理阶段
项目约定 团队可以统一采用其他行长,但应在整个项目中保持一致

下面的代码使用两个空行分隔顶层函数,并使用一个空行划分函数内部的处理阶段:

复制代码
"""演示使用空行划分代码结构。"""


def calculate_total(unit_price, quantity, discount_rate):
    subtotal = unit_price * quantity
    discount_amount = subtotal * discount_rate

    total = subtotal - discount_amount
    return total


def display_total(total):
    print(f"商品总价:{total:.2f} 元")


order_total = calculate_total(19.9, 3, 0.1)
display_total(order_total)

3.3.4 分号与一行多条语句

在 Python 中,也允许把若干条简单语句写在同一行并用分号分隔,但这种写法不利于阅读和调试。常见写法的建议如下:

写法 示例 建议
一行一条语句 x = 1 推荐,代码结构清晰
分号分隔多条语句 x = 1; y = 2 可以运行,但通常不推荐
复合语句写在一行 if ready: start() 通常应拆分为缩进代码块

下面的代码将赋值、计算和输出分别写在不同的行中:

复制代码
"""演示一行只书写一条主要语句。"""

x = 1
y = 2
total = x + y

print(f"计算结果:{total}")
相关推荐
databook5 小时前
用 Pydantic AI 从零搭建一个能干活的 AI Agent
人工智能·python
屏什么录5 小时前
电脑如何录屏幕视频和声音?从工具到代码,7 种方案帮你彻底搞定
前端·音视频开发
康小旺5 小时前
把 markitdown 做成 Windows 桌面版:拖进文档就出 Markdown,附 233MB→64MB 打包裁剪全过程
python
用户360055579005 小时前
Kestrel_VLLM_CUDA -09 · full-GPU decode:单 token 全设备
前端
kyriewen5 小时前
我上手了 Vite+ 1.0:Node 不用自己装,lint 却翻车了
前端·javascript·程序员
upala5 小时前
【仓颉语言入门 · 第二篇 第 6 课】
后端
罗丹丹Luna5 小时前
移动端显示“已提交”以后:SAP 与低代码集成该怎样暴露真实状态
后端·架构
松就是我902985 小时前
你的 PPT 不缺内容,缺一个讲它的人
前端
松就是我902986 小时前
别再熬夜做 PPT 了!输入一个主题,AI 帮你把整套幻灯片做好,还能随便改字
前端