什么是__pycache__?


651

据我了解,缓存是类似文件的加密文件。

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


29
“这是我们给人们的,而不是我们的源代码吗?” -不,您可以使用可安装的漂亮软件包将源代码提供给他们,因此易于使用。
Lennart Regebro

79
尚未有人提及,但是您对缓存的定义很奇怪。缓存非常简单,它是存储数据组件,因此可以更快地处理对该数据的将来请求
里卡多·克鲁兹


1
由于Python 3.8您可以使用环境变量来更改烦人的缓存目录的位置,因此:stackoverflow.com/a/57414308/1612318
Rotareti,

缓存是一种东西的副本,以防万一您再次需要它,以免您不得不回到原始的东西来获取它。它的设计比去原始地方要快。这可能会更快,因为它不必预处理或编译信息。或者它可能是更快的存储,例如RAM中的磁盘缓存或本地磁盘上的Web缓存。它不是由它的性质加密(尽管它有时可能),它并不总是一个“类似的文件的文件” -它可以是一个文件,文件的负载,内存块等等
rjmunro

Answers:


518

当您在python中运行程序时,解释器首先将其编译为字节码(这过于简化),并将其存储在__pycache__文件夹中。如果在其中查看,则会在项目文件夹中找到一堆共享.py文件名的文件,只有它们的扩展名是.pyc或.pyo。它们分别是程序文件的字节码编译版本和优化的字节码编译版本。

作为程序员,您基本上可以忽略它……它所做的只是使您的程序启动更快。脚本更改时,将重新编译它们,如果删除文件或整个文件夹并再次运行程序,它们将重新出现(除非您明确禁止这种行为)

如果您使用的是cpython(这是最常见的实现,因为它是参考实现),并且您不想要该文件夹,则可以通过使用-B标志启动解释器来取消显示该文件夹。

python -B foo.py

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


48
您还可以添加环境变量PYTHONDONTWRITEBYTECODE=<any_value>以永久删除它。
Mark Tolonen 2013年

11
为了澄清,这仅适用于Python 3,对吗?
乔J

11
@JoeJ是的,我认为是事实。python2如果我没记错的话,将编译后的文件放在与原始文件相同的目录中。
scott_fakename 2014年

27
一个重要的警告是,如果缺少.py文件,将使用缓存的.pyc文件而不是.py文件。实际上,只有在删除(或重命名)模块后才会发生这种情况,所以这种情况并不常见,但是如果有些事情在您挠头之后继续运行find的话,则一直存在。名称* .pyc | 您的来源上的xargs rm可能是一个很好的第一反应。
yacc143 2014年

34
find . -name '*.pyc' -delete是的,find具有删除已找到文件的标志,因此您不必使用任何xargs shananigans
vlad-ardelean 2014年

174

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

我不建议您定期删除这些文件或在开发过程中禁止创建文件,因为这可能会影响性能。只需准备好一个递归命令(请参见下文)即可在需要时进行清理,因为在极端情况下字节码可能会变得过时(请参见注释)。

Python程序员通常忽略字节码。事实上,__pycache__*.pyc有共同线看.gitignore文件。字节码不用于分发,可以使用dismodule进行反汇编。


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

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

更换__pycache__*.pyc的Python 2。

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

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


在Windows上,可以使用等效命令(未经测试,欢迎使用批处理脚本):

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

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


运行单元测试是一种方案(在注释中更多),在该方案中删除*.pyc文件和__pycache__文件夹确实很有用。我在我的代码中使用以下几行,~/.bash_profilecl在需要时进行清理。

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

每次运行代码都不会撤消吗?
Holloway 2015年

2
@DoTheEvo:它根本不会被创建,因此下次加载模块时不会加速。没有错误。
彼得·维克托林

7
这不是一个好答案。询问者想知道这些文件的用途。这个答案说“不用担心”,然后使它们消失。
有趣的是

36
绝对要删除它们:这不是没有意义的。在许多情况下,Python都不会高兴地检测不到文件的更改并运行一个缓存文件,并以“为什么f仍然不起作用,我更改了代码,为什么它在不存在的调用中仍然失败”的废话困扰您。尤其是在测试框架中,默认情况下pycache最糟糕。
Mike'Pomax'Kamermans

2
我不同意“不要麻烦删除这些文件”的建议-多次看到此建议,最近一次是肯尼斯·雷茨Kenneth Reitz)的“ How To Python”(“字节码技巧”)
Louis Maddox

38

__pycache__使用以下行时将创建一个文件夹:

import file_name

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


27

更新了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

5

来自官方python教程模块

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

来自Python doc 编程常见问题解答

首次导入模块时(或自创建当前编译文件以来源文件已更改),应在__pycache__包含该.py文件的目录的子目录中创建一个包含编译代码的.pyc 文件。该.pyc文件的文件名以与该.py文件相同的名称开头,以结尾.pyc,其中间部分取决于创建该文件的特定python二进制文件。


5

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

文件名与模块名相同。起始点后面的部分表示创建缓存的Python实现(可以是CPython),其后是版本号。


3

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

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

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


3

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

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

alok@alok:~$ ls
module.py  module.pyc  __pycache__  test.py
alok@alok:~$

2

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


如何避免创建“ pycache ”文件夹,并将所有.pyc命名为与.py文件相同?
阿什瓦尼

1

当您导入模块

import file_name

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

仅导入文件时,它不会仅运行脚本就这样做。

(以前的版本用于将缓存的字节码存储为.pyc文件,这些文件与.py文件位于同一目录中,但是从Python 3开始,它们被移到了一个子目录以使内容变得整洁。)

PYTHONDONTWRITEBYTECODE --->如果将其设置为非空字符串,Python将不会尝试在源模块的导入中写入.pyc文件。这等效于指定-B选项。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.