pythondontwritebytecode=1是最直接有效的禁用pyc方法,它在解释器启动初期即生效,从源头禁止所有模块(含标准库)生成pyc和__pycache__,而手动删除仅临时清理、代码中设sys.dont_write_bytecode=true则晚于标准库初始化且作用范围有限。

PYTHONDONTWRITEBYTECODE=1 是最直接有效的做法,它让 Python 解释器完全跳过 .pyc 文件的生成,且对所有导入路径生效。
为什么设置 PYTHONDONTWRITEBYTECODE 而不是只删 __pycache__?
手动删除 __pycache__ 目录或 .pyc 文件只是临时清理,下次 import 就会立刻重建;而环境变量是运行时控制行为,从源头禁止写入。它比修改代码(如 sys.dont_write_bytecode = True)更早生效——甚至在 site.py 初始化前就起作用,能覆盖标准库模块的字节码生成。
常见错误现象:import 后仍看到 __pycache__ 出现,往往是因为环境变量没生效(比如 shell 中未 export、IDE 未继承系统环境、或用 python -m 启动时被覆盖)。
- Linux/macOS:在终端执行
export PYTHONDONTWRITEBYTECODE=1,再运行python script.py - Windows CMD:用
set PYTHONDONTWRITEBYTECODE=1(仅当前会话) - Windows PowerShell:用
$env:PYTHONDONTWRITEBYTECODE="1" - PyCharm/VS Code:需在运行配置中显式添加该环境变量,不能依赖系统 shell 的 export
sys.dont_write_bytecode=True 和环境变量有什么区别?
sys.dont_write_bytecode 是运行时 Python 级别的开关,必须在解释器启动后、任何 import 前设置才有效(例如放在脚本开头),但它无法阻止标准库模块(如 os、json)在初始化阶段写入字节码——因为它们的导入发生在你的脚本执行之前。
而 PYTHONDONTWRITEBYTECODE 在 C 层解析命令行参数时就被读取,优先级更高。两者可以共存,但环境变量胜出。
- 不推荐在脚本里写
sys.dont_write_bytecode = True来“替代”环境变量 - 如果用
python -c "import sys; sys.dont_write_bytecode=True; import mymod",该设置对mymod生效,但对sys自身不生效(它已加载完毕) - 某些打包工具(如 PyInstaller)默认设为
True,此时环境变量可用来统一覆盖行为
禁用 pyc 后会影响 import 性能或模块重载吗?
影响明确:每次 import 都要重新编译源码,冷启动变慢,尤其对大量小模块的项目(如 Flask 应用加载几十个路由文件)。但日常开发中感知不强;生产部署通常应保留 pyc(或预编译),禁用仅适用于调试、容器镜像构建(避免残留字节码污染)、或只读文件系统场景。
注意:禁用后 importlib.reload() 不会触发新编译——它只重执行已加载模块的代码对象,不涉及磁盘读写,所以和 pyc 无关。
- CI/CD 构建镜像时设
PYTHONDONTWRITEBYTECODE=1可避免因构建机时间戳导致的 pyc 时间不一致问题 - 在 Docker 中,若挂载源码到容器并期望实时修改生效,禁用 pyc 能防止旧字节码缓存干扰
- Python 3.8+ 引入了
__pycache__/xxx.cpython-38.pyc版本化命名,禁用后彻底绕过这套机制,无兼容性顾虑
真正容易被忽略的是:某些 IDE 或测试框架(如 pytest)会用自己的子进程运行 Python,它们未必自动继承你 shell 里 export 的环境变量——务必检查实际运行时的 os.environ.get('PYTHONDONTWRITEBYTECODE') 值是否为 '1'。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











