最稳妥禁用.pyc的方法是设置环境变量pythondontwritebytecode=1,它在python启动时生效,覆盖import、-m等所有场景;python -b仅作用于单次运行;代码中修改sys.dont_write_bytecode对已加载模块无效。

设置 PYTHONDONTWRITEBYTECODE=1 最直接有效
Python 默认会在导入模块时生成 .pyc 文件,存放在 __pycache__ 目录下。想彻底禁用,最稳妥的方式是设置环境变量 PYTHONDONTWRITEBYTECODE=1。这个变量在 Python 启动时就被读取,早于任何代码执行,因此能覆盖所有场景(包括 import、runpy、-m 模式等)。
常见错误是只在某次命令中临时设置却忘了导出,比如写成 PYTHONDONTWRITEBYTECODE=1 python script.py —— 这样变量只对当前 shell 命令生效,但子进程(如 import 触发的编译)可能拿不到;正确做法是先 export PYTHONDONTWRITEBYTECODE=1(Linux/macOS)或 set PYTHONDONTWRITEBYTECODE=1(Windows CMD),再运行 Python。
- 该变量值只要非空(如
1、true、any)即生效,但推荐用1避免歧义 - 它不影响已存在的
.pyc文件,只是阻止新生成;已有缓存仍可能被加载(除非同时删掉__pycache__和顶层.pyc) - 对嵌入式 Python(如某些 IDE 的调试器)也生效,但部分工具(如 PyInstaller 打包过程)会忽略此变量,因其自身控制字节码生成逻辑
python -B 命令行开关适合单次运行
如果只是临时跑一次脚本不想留缓存,用 -B 参数比设环境变量更轻量:python -B script.py。它等价于设置 PYTHONDONTWRITEBYTECODE=1,但仅作用于本次解释器实例。
注意 -B 不影响通过 subprocess 启动的新 Python 进程,那些子进程默认仍会写 pyc;如果子进程也需要禁用,得在子进程中也加 -B 或确保其继承了环境变量。
-
-B不能和-O(优化模式)冲突使用——两者可共存,但-O会生成__pycache__/script.cpython-3x.pyc的优化版,而-B会阻止它生成 - 在 shebang 行里写
#!/usr/bin/env python -B是无效的,Unix shebang 不支持带参数的解释器路径 - VS Code 的
launch.json中可通过"console": "integratedTerminal"+ 预设环境变量实现,而非靠-B
修改 sys.dont_write_bytecode 只对后续 import 生效
在 Python 代码里运行 import sys; sys.dont_write_bytecode = True 确实能禁用后续的 pyc 生成,但它有严重局限:无法影响当前模块自身的编译(即该 .py 文件已加载完毕,其字节码可能早已写入),也不能控制其他模块(如标准库)是否生成缓存。
典型误用场景是把它放在脚本开头,以为能“全局禁用”,结果发现 __pycache__ 还是出现了——因为 import 语句本身触发的编译发生在该赋值之前。
- 仅适用于动态导入(如
importlib.import_module())且你明确控制导入时机的场景 - 它不改变环境变量,所以子进程、新解释器实例完全不受影响
- 如果用
exec()执行字符串代码,该设置同样不生效,因为exec使用独立的编译上下文
IDE 和构建工具常绕过环境变量
PyCharm、VS Code、pytest 等工具内部常自行管理字节码行为。例如 pytest 默认启用 --pyargs 并可能强制写缓存以加速重复测试;PyCharm 的调试器会把 __pycache__ 当作源码状态的一部分,即使设置了 PYTHONDONTWRITEBYTECODE 也可能在后台生成临时 pyc 用于断点解析。
这时候光靠环境变量不够,得查对应工具的配置项:
- PyCharm:Settings → Python Interpreter → 把 “Show all files” 关掉后,
__pycache__不显示,但实际仍存在;真正禁用需在 Help → Edit Custom VM Options 里加-Dpython.dont.write.bytecode=true(仅限 Java 后端的 PyCharm) - pytest:加
--no-cov无用,真正要的是--tb=short无关;必须配合PYTHONDONTWRITEBYTECODE=1且确保 pytest 进程继承该变量(如用env PYTHONDONTWRITEBYTECODE=1 pytest) - Docker 构建中,如果 base image 已预编译过标准库,
PYTHONDONTWRITEBYTECODE只影响你自己的代码,不影响/usr/lib/python3.x/__pycache__
禁用 pyc 看似简单,但跨进程、跨工具链时,真正起效的往往是环境变量的传递时机和范围,而不是变量本身是否存在。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











