Skip to content

3.1 顺序结构 ​

顺序结构是程序最基础的控制流程,指的是代码按照书写的先后顺序,从上到下逐行执行。Python 解释器读取源代码时,默认就是按这个顺序解释和执行每一条语句,没有遇到任何跳转或循环指令前不会改变执行路径。理解顺序结构看似简单,但它涉及语句终止、代码块界定、缩进规则、占位语句等细节,这些细节会贯穿后续所有控制结构的学习。

3.1.1 程序默认自上而下的执行顺序 ​

Python 程序的默认执行顺序是从源文件的第一行开始,依次向下执行每一条语句,直到文件末尾或者遇到 return、break、continue、sys.exit() 等显式的跳转语句。这种自上而下的执行方式意味着,写在后面的语句依赖前面语句已经产生的结果。如果调换语句顺序,程序的执行结果可能完全不同。

python
# 演示自上而下的执行顺序
print("第一步:准备数据")
data = [10, 20, 30]
print("第二步:处理数据")
total = sum(data)
print("第三步:输出结果")
print("总和是", total)

上述代码会严格按四条 print 与中间赋值语句的书写顺序执行。如果把 total = sum(data) 移到 print("总和是", total) 之后,运行时会报 NameError,因为使用 total 时它尚未被创建。这种依赖关系在所有编程语言中都存在,编写代码时要在脑海中模拟执行顺序,确保每条语句在执行时它所需要的数据已经准备好。

3.1.2 语句结束符(换行符作为语句终止标志) ​

与 C、Java 等语言使用分号作为语句结束符不同,Python 默认以换行符作为一条语句的终止标志。每写完一条语句,按下回车换行,这条语句就结束了,下一条语句从新的一行开始。这种设计让 Python 代码在视觉上更接近自然语言段落,不需要在每行末尾加分号,阅读起来也更为清爽。

python
# 每条语句独占一行,无需分号
user_name = "张三"
age = 45
score = 88.5

print(user_name)
print(age)
print(score)

这种以换行作为语句终止的设计也会带来一些细节。当一条语句较长需要换行书写时,必须显式告诉解释器这条语句还没结束。常见做法是使用反斜杠 \ 续行,或者利用括号内的换行会自动延续的规则。括号续行更推荐,因为它不容易出错,也符合 PEP 8 规范。

python
# 使用反斜杠续行(不推荐,容易遗漏空格)
total = 100 + 200 + 300 + \
        400 + 500
print(total)  # 1500

# 使用括号续行(推荐)
total = (100 + 200 + 300 +
         400 + 500)
print(total)  # 1500

3.1.3 使用分号 ; 在同一行分隔多条语句(实际应用规范禁止) ​

Python 语法上允许在一行内用分号 ; 分隔多条语句,这种写法虽然能被解释器正确识别并执行,但在 PEP 8 规范中被明确禁止,实际项目中几乎不会使用。这种写法会牺牲代码的可读性,调试时也难以在单条语句上设置断点。

python
# 语法允许,但规范禁止
user_name = "张三"; age = 45; score = 88.5
print(user_name); print(age); print(score)

上述代码在语法上完全正确,能够正常运行并输出三行结果。但每行只做一件事是更清晰的写法,团队协作中也更容易做代码审查。仅在交互式解释器中临时调试时,偶尔会把多条简单语句写在一行以节省空间,正式代码中应避免这种风格。

分号的适用场景

分号在 Python 中并不是无用的符号,它仍有合法用途。比如在交互式解释器中输入一行临时调试代码,或者在脚本中需要让 python -c 执行多条语句时,分号能派上用场。但在普通的源代码文件中,遵循 PEP 8 规范,一行只写一条语句。

3.1.4 代码块通过缩进(4个空格或Tab)界定,无需大括号 ​

Python 用缩进界定代码块,而不是像 C、Java 那样使用大括号 {}。属于同一代码块的所有语句必须保持相同的缩进量,缩进增加表示进入内层代码块,缩进减少表示退出该代码块。这种设计强制开发者用视觉对齐来表达代码结构,代码的层次关系清晰可见。

PEP 8 规范推荐每一级缩进使用 4 个空格,不要混用 Tab 和空格。从 Python 3 开始,同一文件中混用 Tab 和空格会触发 TabError,解释器拒绝执行。建议在编辑器中将 Tab 键设置为自动插入 4 个空格,避免这类问题。

python
# 用缩进界定代码块
if True:
    print("进入 if 代码块")
    print("这是同一代码块的第二条语句")
    print("缩进量相同,属于同一块")
print("缩进减少,退出 if 代码块")

上述代码中,前三条 print 语句都缩进了 4 个空格,属于 if 语句的代码块。最后一条 print 语句缩进量为 0,回到了 if 之外。缩进本身就是语法的一部分,写错缩进会直接导致 IndentationError,程序无法运行。这一点和其他语言用大括号界定代码块在思维上有明显差异,初学者需要适应。

3.1.5 缩进级别的一致性要求(同一代码块内缩进量必须相同) ​

同一代码块内的所有语句必须保持完全相同的缩进量,多一个空格或少一个空格都会被解释器视为语法错误。这种严格的一致性要求,确保了代码块在视觉上的清晰,也避免了歧义。空格数量本身没有硬性规定(虽然 PEP 8 推荐 4 个空格),但同一代码块内的所有语句必须一致。

python
# 同一代码块内缩进必须一致
if True:
    print("第一条")     # 4 个空格缩进
    print("第二条")     # 4 个空格缩进,正确

下面的写法就是错误的,同一代码块内缩进不一致会导致 IndentationError:

python
# 错误示范:缩进不一致
if True:
    print("第一条")     # 4 个空格
      print("第二条")   # 6 个空格,IndentationError
python
# 错误示范:混用 Tab 和空格(Python 3 会报 TabError)
if True:
	print("用 Tab 缩进")      # Tab 字符
    print("用空格缩进")        # 4 个空格,TabError

编辑器配置

现代编辑器(如 VS Code、PyCharm)都支持把 Tab 键自动转换为空格。建议在项目开始时就统一缩进风格,避免后期合并代码时出现混用 Tab 和空格的问题。Python 社区的标准是 4 个空格,遵循这一惯例能让你的代码在任何环境中都正确运行。

3.1.6 空行不影响程序执行顺序(用作代码分段) ​

空行在 Python 中没有语法含义,解释器会忽略空行,不会因为空行的存在而改变执行顺序。空行的作用是帮助人类阅读,把逻辑上相关的语句组织成段落,提升代码的可读性。在函数之间、类之间、不同逻辑模块之间适当使用空行,是良好编码习惯的体现。

python
# 空行用于代码分段
def calculate_total(items):
    subtotal = sum(items)
    tax = subtotal * 0.1
    return subtotal + tax


# 上面的空行把两个函数分开
def print_report(items):
    total = calculate_total(items)
    print("明细:", items)
    print("总计:", total)


# 主程序逻辑
data = [100, 200, 300]
print_report(data)

上述代码中,函数定义之间、函数与主程序之间都有空行分隔。这些空行不影响执行结果,但让代码结构清晰可读。PEP 8 对空行有具体建议:顶层函数和类定义之间用两个空行分隔,类内的方法之间用一个空行分隔,函数内部逻辑段落之间可以适当使用单个空行。这些是约定,不是强制,但遵循约定能让代码风格统一。

3.1.7 pass 空语句在顺序结构中的占位作用 ​

pass 是 Python 中的一个特殊语句,它什么都不做,是一条空操作语句。pass 的主要用途是占位,让语法结构完整。Python 的代码块要求至少有一条语句,当一个代码块暂时没有内容时,必须用 pass 填充,否则会报 SyntaxError。

python
# pass 作为空函数的占位
def to_be_implemented():
    pass


# pass 作为空类的占位
class EmptyClass:
    pass


# pass 作为空 if 块的占位
if True:
    pass  # 暂时不做任何处理

在顺序结构中,pass 也会出现。比如在编写函数框架时,先把所有函数定义出来,函数体暂时用 pass 占位,再逐个填充实现。这种先搭骨架后填血肉的开发方式,能让程序的整体结构尽早可运行,方便逐步完善。

python
# 先搭骨架,再用 pass 占位
def read_data():
    pass  # 待实现


def process_data(data):
    pass  # 待实现


def save_result(result):
    pass  # 待实现


# 主流程已经可以运行,函数实现后续补充
data = read_data()
result = process_data(data)
save_result(result)

上述代码定义了三个函数,函数体都是 pass,主流程把它们串起来调用。整个程序能够正常运行,只是每个函数都返回 None,实际效果为空。等真正实现某个函数时,把 pass 替换成具体逻辑即可。这种开发模式在原型设计和接口约定阶段非常实用。

pass 与注释的区别

注释是被解释器忽略的文本,写在代码中只为人类阅读,不能作为代码块的内容。pass 是一条真正的语句,会被解释器执行,只是它执行时什么都不做。当语法要求代码块至少有一条语句时,注释无法替代 pass,必须用 pass 或其他语句填充。

学完本节,你应该理解了 Python 程序的默认执行顺序,以及围绕顺序结构展开的语句终止、缩进规则、空行作用和占位语句等细节。下一节将进入分支结构的学习,看看程序如何根据条件选择不同的执行路径。

练习题 ​

第 1 题:写出下列代码的输出结果 ​

阅读下面这段顺序结构代码,在不运行的情况下写出它的输出。

python
a = 5
b = a + 3
c = b * 2
print("a =", a)
print("b =", b)
print("c =", c)
a = a + b
print("a =", a)
参考答案

输出如下。第四条 print 中的 a 已经被重新赋值,所以输出 13。

a = 5
b = 8
c = 16
a = 13

这段代码体现了顺序结构的核心特点:每条语句依赖前面语句已经产生的结果,调换顺序会让结果完全不同。

第 2 题:编写一段计算商品总价的代码 ​

假设有三种商品,单价分别是 12.5 元、8.0 元、30.0 元,购买数量分别是 2 件、3 件、1 件。请按顺序结构编写一段代码,先分别计算每种商品的金额,再累加得到总价,最后打印总价。

参考答案
python
price_a = 12.5
price_b = 8.0
price_c = 30.0

amount_a = price_a * 2
amount_b = price_b * 3
amount_c = price_c * 1

total = amount_a + amount_b + amount_c
print("总价是", total)

代码按照先定义单价、再算金额、最后累加的顺序书写。每一步都依赖前一步已经准备好的数据,调换顺序会导致 NameError。

第 3 题:分析下面代码的执行问题并修正 ​

下面这段代码尝试先打印变量 result,再对它赋值。请说明会出什么问题,并调整语句顺序使其能正常运行。

python
print("结果是", result)
result = 10 + 20
参考答案

原始代码会抛出 NameError: name 'result' is not defined。Python 按顺序执行,执行到 print 时 result 尚未创建。

修正后的代码把赋值语句放到打印之前:

python
result = 10 + 20
print("结果是", result)

这体现了顺序结构中语句依赖关系的约束:使用一个变量之前,必须先让它有值。

第 4 题:项目练习题(命令行任务管理器) ​

命令行任务管理器项目启动时需要先初始化存储结构,再展示欢迎信息,最后进入主流程。请用顺序结构写出这部分骨架代码,函数体暂时用 pass 占位。

参考答案
python
def init_storage():
    pass  # 后续实现存储初始化


def show_welcome():
    pass  # 后续打印欢迎信息


def main_loop():
    pass  # 后续实现主交互循环


# 主流程顺序执行
init_storage()
show_welcome()
main_loop()

这种先搭骨架后填实现的方式让程序整体结构尽早可运行,每个函数用 pass 占位,后续逐个替换为具体逻辑。这是顺序结构中 pass 语句的典型用法。

常见错误 ​

错误 1 · NameError: name 'result' is not defined

原因:在使用变量之前未对其赋值。Python 按顺序执行语句,遇到尚未创建的变量名时会抛出此异常。

解决:检查语句顺序,确保变量在使用前已经定义。把赋值语句移到使用该变量的语句之前。

错误 2 · IndentationError: unexpected indent

原因:同一代码块内的缩进量不一致,多了一个或几个空格。Python 用缩进界定代码块,缩进量必须严格统一。

解决:检查报错行及前一行的缩进,统一为 4 个空格。在编辑器中开启显示空白字符有助于发现多余的空格。

错误 3 · TabError: inconsistent use of tabs and spaces in indentation

原因:同一文件中混用了 Tab 字符和空格进行缩进。Python 3 不允许混用,会直接拒绝执行。

解决:在编辑器中将 Tab 键设置为自动插入 4 个空格,然后把文件中所有 Tab 替换为空格。

错误 4 · SyntaxError: unexpected EOF while parsing

原因:代码块(如 if、for、def)没有写任何语句就结束了。Python 要求代码块至少包含一条语句。

解决:在代码块中添加 pass 语句作为占位,后续再补充具体实现。