__pycache__是Python解释器自动生成的字节码缓存目录,用于加速模块导入;它只在模块被import时生成.pyc文件,不为直接执行的顶层脚本生成,且文件名中的cpython-312标识解释器类型与Python主版本,确保字节码兼容性。

Python 自动创建 __pycache__ 文件夹,是因为解释器在导入模块时默认启用字节码缓存机制——它不是 bug,是设计使然;删掉它不会影响代码功能,但会牺牲后续启动速度。
为什么 __pycache__ 只在导入模块时生成,而不是运行主脚本时?
Python 只对被 import 的模块生成 .pyc 缓存,不为直接执行的 __main__.py 或顶层脚本生成(除非该脚本又被其他模块 import)。比如:
-
python main.py:若main.py仅作为入口、不被其他模块导入,则通常不生成main.cpython-312.pyc -
from utils.logger import setup:只要utils/logger.py被导入,就会在utils/__pycache__/下生成对应.pyc - 即使
main.py里写了import os,标准库的.pyc一般不落盘(它们已预编译并内置在lib/python3.12/__pycache__/中)
__pycache__ 文件名里的 cpython-312 是什么?
这部分标识了字节码的兼容性边界,直接影响能否复用缓存:
-
cpython表示使用 CPython 解释器(非 PyPy、Jython) -
312是 Python 主版本号(即 3.12),不同小版本(如 3.12.0 vs 3.12.1)通常兼容,但跨大版本(3.11 → 3.12)绝对不兼容 - 这意味着:换 Python 版本后,旧
.pyc会被忽略,重新编译并写入新命名的文件 - 如果你在 CI 中切换 Python 版本,或本地混用 pyenv 多版本,
__pycache__会“自动分家”,不会误用
删掉 __pycache__ 会影响性能吗?实测差异在哪?
影响真实存在,尤其在模块多、启动频次高的场景:
Python 编程规范与最佳实践。强制 PEP 8 代码风格、语法校验、单元测试执行,适用于代码编写、审查和重构。触发词:Python、代码规范、py_compile、单元测试。
- 单次运行:感知不强,可能慢几十毫秒(编译一个
.py通常 - 单元测试(如 pytest 运行 200 个 test 文件,每个 import 5 个模块):冷启动比热启动慢 3–10 倍,主要卡在重复编译
- Django/Flask 启动:首次加载大量中间件、路由、模型时,
__pycache__能省下数百 ms 到 1 秒不等 - 注意:这个加速只发生在「源码未变」的前提下;一旦改了
logger.py,对应.pyc就失效,下次仍要编译
Git 提交 __pycache__ 吗?为什么多数项目都忽略它?
不该提交,原因很实际:
-
__pycache__是纯派生文件,和.o、.class一样,属于构建产物 - 不同开发者 Python 版本可能不同(3.11 / 3.12 / 3.13),各自生成的
.pyc文件名不一致,强行提交会导致 Git 冲突或无效缓存 - CI 环境每次都是干净 clone,缓存无意义;本地开发时删除再重建成本极低
- 正确做法:在
.gitignore里加一行__pycache__/(结尾斜杠确保匹配目录而非文件)
真正容易被忽略的是:缓存有效性完全依赖文件修改时间戳。如果通过 rsync、IDE 同步或某些编辑器保存机制导致 .py 时间戳被重置(早于 .pyc),Python 会误判“源码未改”,加载损坏或过期的字节码——这种问题难复现、难调试,比没缓存更麻烦。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










