一行 Python 代码是怎么运行的:从表达式到输出的图解
用变量状态、当前行和输出区,逐步看懂 Python 如何从上到下运行一段订单脚本,以及修改输入后执行轨迹为什么会改变。
本文目录 6 节 · 点击展开
Python 代码不是一次性把整页“算完”。默认情况下,它从上到下走到一行、完成这一行,再去下一行。运行时有些变化能在终端里看到,更多变化却藏在程序内部:表达式先得到结果、变量记住结果、条件得到 True 或 False,最后才可能产生输出。
这一章不要求先记语法。先把代码当成一条可以逐站观察的轨道,学会回答四个问题:现在运行哪一行?这一行拿到什么?内部状态怎样改变?有没有产生输出?
一行赋值,不是把等号两边同时连起来
先看一行可以直接运行的代码:
paid_total = 129.0 + 199.0
这里的 = 不是数学题里的“左右相等”。Python 会先处理右侧,再让左侧的名字记住结果。
paid_total = 129.0 + 199.0- 输入 · 01读取右侧表达式
129.0 + 199.0此时还没有名为 paid_total 的变量。 - 当前行 · 02先计算右侧
129.0 + 199.0 → 328.0表达式先产生一个值。 - 之后 · 03名字绑定到结果后面的代码可以通过名字取回这个值。
paid_total328.0
最后一格特意写着“输出暂无”:变量状态改变,不等于屏幕会出现文字。 只有代码明确调用 print() 等输出动作时,终端才会显示内容。
paid_total = 129.0 + 199.0
print(paid_total)
这两行运行后,变量仍然保存 328.0,终端另外显示:
328.0
到这里,可以先把几个词对应起来:
| 看到的东西 | 在这段代码里是什么 | 它负责什么 |
|---|---|---|
| 代码行 | paid_total = 129.0 + 199.0 | 告诉 Python 当前要做的事 |
| 表达式 | 129.0 + 199.0 | 计算并产生值 328.0 |
| 变量状态 | paid_total → 328.0 | 让后续代码能通过名字取得值 |
| 输出 | 终端里的 328.0 | 把结果显示给运行代码的人 |
8 行订单脚本怎样从上到下运行
现在看一段完整但很短的订单脚本。先复制运行,不用急着解释每个符号:
orders = [
{"order_no": "A001", "amount": 129.0, "status": "已支付"},
{"order_no": "A002", "amount": 88.0, "status": "已退款"},
]
for order in orders:
if order["status"] == "已支付":
print(order["order_no"], order["amount"])
算上空行,这正好是 8 行。空行方便人阅读,不会产生运行步骤。第 1~4 行先准备数据;第 6~8 行再逐条查看订单、判断状态,并决定是否输出。
orders = [ {A001 · 129.0 · 已支付}, {A002 · 88.0 · 已退款},]空行 · 不执行for order in orders:会回来 if order[“status”] == “已支付”:每轮判断 print(…)True 才到达orders2 条订单
当前 order随每轮改变
A001 129.0A002 没有通过判断,所以没有第二行输出。- 步骤 01当前行 1~4
orders = […]之前 没有订单数据
之后 orders 绑定到 2 条订单
- 步骤 02当前行 6
for order in orders:输入 第 1 条 A001
之后 当前 order 是 A001
- 步骤 03当前行 7
status == “已支付”条件 “已支付” == “已支付”
结果 True,进入第 8 行
- 步骤 04当前行 8
print(…)读取 A001 和 129.0
输出 A001 129.0
- 步骤 05回到行 6
for order in orders:输入 第 2 条 A002
之后 当前 order 改为 A002
- 步骤 06当前行 7
status == “已支付”条件 “已退款” == “已支付”
结果 False,跳过第 8 行
- 步骤 07回到行 6
没有下一条订单状态 逐条处理结束
最终输出 只有 A001 129.0
这里最容易忽略的是:代码虽然只写了一次第 6、7 行,运行时却会为了不同订单回到它们。第 8 行也不是“排在后面就一定执行”,它只有在第 7 行得到 True 时才会到达。循环和判断会在后面的章节单独拆解;现在先会沿轨道读懂它们。
只改一个输入,哪一段轨迹会改变
学习代码最有效的方法之一,是先预测,再只改一个值。把 A002 的状态从“已退款”改成“已支付”,其他代码一字不动:
orders = [
{"order_no": "A001", "amount": 129.0, "status": "已支付"},
{"order_no": "A002", "amount": 88.0, "status": "已支付"},
]
for order in orders:
if order["status"] == "已支付":
print(order["order_no"], order["amount"])
前半段轨迹完全相同:准备两条订单、处理 A001、输出 A001。变化直到第二次运行第 7 行时才出现。
“已退款” == “已支付”条件结果:False跳过第 8 行
“已支付” == “已支付”条件结果:True继续执行第 8 行
修改后的完整输出是:
A001 129.0
A002 88.0
这就是调试代码时很重要的思路:不要只问“结果怎么变了”,而要找到第一处产生不同结果的当前行。这里不是第 6 行拿订单时出错,而是第 7 行的条件从 False 变成了 True,它又决定第 8 行是否执行。
如果输入缺少字段,脚本会停在哪里
运行轨道也能帮助定位错误。假设第二条订单没有 status 字段:
orders = [
{"order_no": "A001", "amount": 129.0, "status": "已支付"},
{"order_no": "A002", "amount": 88.0},
]
for order in orders:
if order["status"] == "已支付":
print(order["order_no"], order["amount"])
第一条订单仍能正常输出。处理第二条订单时,第 7 行需要读取 order["status"],但这条数据没有这个字段,因此脚本在这里停止,并显示 KeyError: 'status'。第 8 行不会为 A002 执行。
order[“status”]输入里找不到 status → 无法完成条件求值 → 脚本停止现在只需会找停止点,不必急着处理异常。后续“错误与调试”章节会专门解释错误怎样产生、怎样找到合适的处理方式。
按任务学习,而不是背语法目录
这段 8 行脚本已经包含后续课程的大部分主线:字符串和数字表示字段值,列表保存多条订单,字典保存一条订单的多个字段,判断决定是否处理,逐条执行让每条订单经过同一段代码,输出把结果展示出来。
学习每段新代码时,固定做四件事:
- 先不运行,猜第一行输出会是什么。
- 再运行,沿着代码行找到预测相同或不同的位置。
- 只修改一个输入值,再观察第一处分岔点。
- 用自己的话说出“输入、当前行、状态变化、输出”。
系列后续会用订单、SKU、库存、文件和 JSON 继续这条轨道:先看见数据,接着看见条件、循环与函数怎样让代码流动,最后把外部数据接入一份完整脚本。类与对象放在主线之后作为选修,因为很多几十行以内的自动化任务,用基础数据和函数已经足够。
第一次运行,只完成最小闭环
如果已经能运行 Python 3,可以跳过这一节。在终端尝试下面三个命令之一:
python --version
python3 --version
py --version
只要其中一个显示 Python 3 的版本号,就可以创建 demo.py:
print("Hello Python")
进入文件所在目录,用刚才可用的命令运行,例如:
python demo.py
看到 Hello Python 就完成了“写入代码 → 保存文件 → 运行 → 看见输出”的最小闭环。这里不展开 IDE、虚拟环境和包管理;先把注意力留给代码本身怎样运行。