大家好,我是正在实战各种 AI 项目的程序员晚枫。
理解常用字节码指令,看懂 dis 模块的输出。这一讲,你终于能看懂 Python 源代码背后的秘密了。
📖 开篇:字节码是什么?
我们写 Python 代码,Python 不会直接执行。
它会先「编译」成一种中间格式——字节码(Bytecode),然后由 Python 虚拟机(PVM)执行。
1 | # 这行简单的代码 |
Python 的 dis 模块可以让我们看到这些字节码:
1 | import dis |
小技巧:在 Jupyter Notebook 里,用
dis.dis(函数名)可以分析任何函数的字节码。这是理解 Python 运行机制的第一步。
📖 加载/存储指令
这是最常用的指令,用来在变量和栈之间移动数据:
| 指令 | 作用 | 示例 |
|---|---|---|
| LOAD_CONST | 把常量加载到栈上 | x = 1 → LOAD_CONST 1 |
| LOAD_FAST | 加载局部变量 | print(x) → LOAD_FAST x |
| LOAD_GLOBAL | 加载全局变量 | print(len) → LOAD_GLOBAL len |
| STORE_FAST | 把栈顶的值存到局部变量 | x = 1 → STORE_FAST x |
| STORE_GLOBAL | 存到全局变量 | global x; x = 1 |
| DELETE_FAST | 删除局部变量 | del x → DELETE_FAST x |
看一个完整例子:
1 | import dis |
输出:
1 | 2 0 LOAD_CONST 1 (1) |
你注意到了吗?
x存储在局部变量槽 0((x)是注释)- 每一步都有「操作码 + 操作数」的组合
- RETURN_VALUE 负责把最终结果返回
🔧 运算指令
栈式虚拟机的工作方式:先压入操作数,再执行运算指令。
| 指令 | 作用 | 对应操作 |
|---|---|---|
| BINARY_ADD | 弹出两个值相加 | a + b |
| BINARY_SUBTRACT | 弹出两个值相减 | a - b |
| BINARY_MULTIPLY | 弹出两个值相乘 | a * b |
| BINARY_TRUE_DIVIDE | 弹出两个值相除 | a / b |
| BINARY_FLOOR_DIVIDE | 整除 | a // b |
| BINARY_MODULO | 取模 | a % b |
| BINARY_POWER | 幂运算 | a ** b |
比较运算
| 指令 | 作用 |
|---|---|
| COMPARE_OP | 比较运算(<、>、== 等) |
| POP_JUMP_IF_TRUE | 栈顶为真则跳转 |
| POP_JUMP_IF_FALSE | 栈顶为假则跳转 |
1 | def compare_demo(a, b): |
📞 函数调用指令
函数调用是字节码里最复杂的操作之一:
| 指令 | 作用 |
|---|---|
| CALL_FUNCTION | 调用函数(Python 3.11 之前) |
| CALL_METHOD | 调用方法(Python 3.11 之前) |
| PREP_CALL | 准备调用(Python 3.11+) |
| RETURN_VALUE | 返回值 |
1 | def greet(name): |
Python 3.11 的重大变化
Python 3.11 对字节码做了大幅优化,指令更精简:
CALL_FUNCTION被替换为PRECALL+CALL- 增加了
SWAP、COPY等新指令 - 异常处理更快
🔍 实战:用 dis 分析性能问题
字节码分析不仅是学习工具,还能帮我们优化代码:
1 | import dis |
看字节码行数:列表推导式往往比等效的 for 循环更少字节码指令,执行更快。
⚠️ 常见陷阱
陷阱1:局部变量命名冲突
1 | # 慢写法 |
陷阱2:在循环内重复获取属性
1 | # 慢 |
💡 本节作业
- 用
dis.dis()分析你最常用的一个函数 - 找出函数里最耗时的字节码是什么
- 尝试用列表推导式替换一个普通 for 循环,用 dis 对比
🎯 本讲总结
加载/存储指令:LOAD_FAST、STORE_FAST、LOAD_CONST——栈式虚拟机的基本操作。
运算指令:BINARY_ADD、BINARY_MULTIPLY 等——先压栈,再运算。
函数调用:CALL_FUNCTION、RETURN_VALUE——复杂的调用约定。
实战工具:dis 模块是分析字节码的瑞士军刀。
📚 推荐教材
《Python 编程从入门到实践(第 3 版)》 | 《流畅的 Python(第 2 版)》 | 《CPython 设计与实现》
🔗 课程导航
← 上一讲:字节码执行 | 下一讲:数字类型实现 →
💬 联系我
| 平台 | 账号/链接 |
|---|---|
| 微信 | 扫码加好友 |
| B 站 | Python 自动化办公社区 |
主营业务:AI 编程培训、企业内训、技术咨询