什么是__pycache__?

据我所知,缓存是类似文件的加密文件。

我们用__pycache__文件夹做什么?它是我们给人们的东西而不是我们的源代码吗?它只是我的输入数据吗?这个文件夹不断被创建,它是用来做什么的?

527980 次浏览

当你在Python中运行一个程序时,解释器首先将其编译为字节码(这是一种过度简化)并将其存储在__pycache__文件夹中。如果你在那里查看,你会发现一堆文件共享项目文件夹中.py文件的名称,只有它们的扩展名将是.pyc.pyo。这些分别是程序文件的字节码编译版本和优化字节码编译版本。

作为一名程序员,你可以在很大程度上忽略它……它所做的只是让你的程序启动得更快一点。当你的脚本发生变化时,它们会被重新编译,如果你删除文件或整个文件夹并再次运行你的程序,它们会重新出现(除非你特别禁止这种行为)。

当您将代码发送给其他人时,通常的做法是删除该文件夹,但是否删除并不重要。当您使用版本控制(git)时,此文件夹通常列在忽略文件(.gitignore)中,因此不包括在内。

如果您使用的是CPython(这是最常见的,因为它是参考实现)并且您不想要该文件夹,那么您可以通过使用-B标志启动解释器来抑制它,例如

python -B foo.py

正如tcaswell所指出的,另一种选择是将环境变量PYTHONDONTWRITEBYTECODE设置为任何值(根据Python的手册页,任何“非空字符串”)。

__pycache__是一个包含Python 3字节码已编译并准备好执行的文件夹。

我不建议在开发过程中经常费力地删除这些文件或抑制创建,因为这会浪费你的时间。只需准备一个递归命令(见下文),以便在需要时进行清理,因为字节码在边缘情况下可能会变得陈旧(见注释)。

Python程序员通常忽略字节码。事实上,__pycache__*.pyc.gitignore文件中常见的行。字节码不适合分发,可以使用#3模块拆解。


如果您使用的是OS X,您可以通过从项目的根文件夹运行以下命令轻松隐藏项目中的所有这些文件夹。

find . -name '__pycache__' -exec chflags hidden {} \;

对于Python 2,将__pycache__替换为*.pyc

这会在所有这些目录(. pyc文件)上设置一个标志,告诉Finder/Textmate2将它们从列表中排除。重要的是字节码在那里,它只是隐藏了。

如果您创建新模块并希望隐藏新字节码或删除隐藏的字节码文件,请重新运行命令。


在Windows上,等效的命令可能是(未测试,欢迎批处理脚本):

dir * /s/b | findstr __pycache__ | attrib +h +s +r

这与使用右键单击>隐藏…浏览项目隐藏文件夹相同。


运行单元测试是删除*.pyc文件和__pycache__文件夹确实有用的一种场景(更多在注释中)。我在我的~/.bash_profile中使用以下行,并在需要时运行cl来清理。

alias cpy='find . -name "__pycache__" -delete'alias cpc='find . -name "*.pyc"       -delete'...alias cl='cpy && cpc && ...'

而且最近

# pip install pycleanpyclean .

在3.2及更高版本中,Python将. pyc编译的字节码文件保存在名为__pycache__的子目录中,该子目录位于源文件所在的目录中,文件名标识创建它们的Python版本(例如script.cpython-33.pyc)

从3.7+文档更新的答案:

为了加快加载模块,Python缓存编译版本的__pycache__目录下的每个模块module.version.pyc,其中版本编码的格式编译文件;它通常包含Python版本号。对于例如,在CPython 3.3版中,spam.py的编译版本将被缓存为__pycache__/spam.cpython-33.pyc。这个命名约定允许来自不同版本和不同版本的编译模块Python的共存。

来源:https://docs.python.org/3/tutorial/modules.html#compiled-python-files

也就是说,这个目录是由Python生成的,存在是为了让你的程序运行得更快。它不应该致力于源代码控制,应该与你的本地源代码和平共存。


__pycache__是一个包含由python自动生成的字节码缓存文件的目录,即编译的python或.pyc文件。你可能想知道为什么Python,一种“解释”语言,有任何编译的文件。这个so问题解决了这个问题(这绝对值得阅读这个答案)。

python文档更深入地了解了它是如何工作的以及它为什么存在:

  • 它是在python 3.2中添加的,因为现有的在同一目录中维护.pyc文件的系统会导致各种问题,例如当程序使用不同版本的Python解释器运行时。有关完整功能规范,请参阅PEP 3174

当您使用以下行时,会创建__pycache__文件夹:

import file_name

或者尝试从您创建的另一个文件中获取信息。这使得第二次运行程序以打开另一个文件时更快。

python解释器编译*. py脚本文件并将编译结果保存到__pycache__目录。

当项目再次执行时,如果解释器识别出*. py脚本没有被修改,它会跳过编译步骤并运行存储在__pycache__文件夹中的先前生成的*. pyc文件。

当项目很复杂时,您可以缩短项目运行前的准备时间。如果程序太小,您可以通过使用python -B abc.pyB选项来忽略它。

来自官方python教程模块

为了加快加载模块的速度,Python将每个模块的编译版本缓存在__pycache__目录下的名称module.version.pyc下,其中版本对编译文件的格式进行编码;它通常包含Python版本号。例如,在CPython 3.6版本中,spam.py的编译版本将缓存为__pycache__/spam.cpython-36.pyc

来自python doc编程常见问题

当第一次导入模块时(或者当源文件在创建当前编译文件后发生变化时),应该在包含.py文件的目录的__pycache__子目录中创建一个包含编译代码的. pyc文件。.pyc文件的文件名将以与.py文件相同的名称开头,以.pyc结尾,中间组件取决于创建它的特定python二进制文件。

执行python脚本将导致在内存中生成字节码并保留直到程序关闭。如果导入了一个模块,为了更快的可重用性,Python将创建一个缓存. pyc(PYC是'Python''编译')文件,其中缓存正在导入的模块的字节码。想法是通过避免重新编译(编译一次,运行多次策略)来加快python模块的加载。

文件的名称与模块名称相同。初始点之后的部分指示创建缓存(可能是CPython)的Python实现,后跟其版本号。

当解释器编译代码时,Python版本2. x将具有. pyc

当解释器编译代码时,Python版本3. x将具有__pycache__

alok@alok:~$ lsmodule.py  module.pyc  __pycache__  test.pyalok@alok:~$

当你导入模块

import file_name

Python将编译后的字节码存储在__pycache__目录中,以便将来的导入可以直接使用它,而不必再次解析和编译源代码。

它不会仅在运行脚本时执行此操作,仅在导入文件时执行此操作。

(以前的版本用于将缓存的字节码存储为. pyc文件,这些文件与. py文件散落在同一目录中,但从Python 3开始,它们被移动到子目录以使事情更整洁。)

Python不写字节码--->如果将其设置为非空字符串,Python不会尝试在导入源模块时写入. pyc文件。这相当于指定-B选项。

__pycache__中的字节码是否会在下次启动应用程序时自动调用?即:如果我们第一次运行某个应用程序main.py,并且所有必要的模块都被编译并存储在pycache中,那么下一次即使我调用python main.py,它们也会自动使用吗?或者我们将不得不调用python _pycache_/main.pyc