1. 概述
在Python工作目录下,如果执行某文件后经常会自动生成一个__pycache__文件夹。如图1所示,当执行demo.py文件以后,在根目录和package文件夹下面都自动生成了__pycache__文件夹。这个__pycache__文件夹是什么东西呢?从字面意思理解,应该是Python的缓存文件夹,但是缓存的到底是什么呢?
图12. 几个基本概念
2.1 源代码(source code)
我们每天编写的Python、Java、C++等代码通常指的就是源代码,源代码的特点是人类可读。但是CPU只能读懂二进制,看不懂我们写的源代码,因此还需要进行编译(compile)。
2.2 字节码(byte code)
因为CPU读不懂源代码,因此需要对源代码进行编译:把源代码(原始语言)转换成另一种编程语言(目标语言)的过程称为编译。但是在Python中,并不是直接把源代码编译为机器码的。还需要经历一个中间语言,即字节码。字节码以字节的形式方式存储,如
b'd\x00Z\x00e\x01e\x02e\x00\x83\x01\xa0\x03\xa1\x00e\x00d\x01\x83\x03Z\x04e\x04j\x05Z\x06e\x07d\x02e\x06\x9b\x00\x9d\x02\x83\x01\x01\x00d\x03S\x00'
2.3 机器码(machine code)
机器码是CPU可直接解读的代码,也称为native code。[1]
2.4 解释器(interpreter)
在Python中,解释器是一种让Python程序运行起来的程序,在IDE中可以看到对解释器进行选择。
图2 解释器选择2.5 虚拟机(virtual machine)[2]
生成了字节码之后,就会被发送到Python虚拟机(Python virtual machine, PVM)中执行,因此Python虚拟机是Python解释器的最后一步。
3. Python工作机制[3]
图3
- 对于一个*.py文件,在执行过程中解释器会先把*.py文件编译为字节码,并缓存在*.pyc文件中;
- 编译产生的字节码被python虚拟机逐行执行
4. 为什么要有__pycache__文件夹?
如上文所说,字节码缓存在*.pyc文件中,而__pycache__文件夹正是缓存*.pyc地方。*.pyc文件的命名格式是<module>.<interpreter_version>.pyc,如下图所示。注意,对于被导入的module才会生成对应的*.pyc文件,因此下图中虽然执行的是python ./demo.py,但是并没有看到有demo.cpython-39.pyc文件生成。
图4那么最根本的问题来了,为什么要这么做呢?为什么要设置一个中间代码呢?这个背后的逻辑和Java是一样,主要是为了解决跨平台性。Java的执行过程也是先把源代码编译为字节码,然后进入Java虚拟机进行执行。Java虚拟机会屏蔽掉不同操作系统以及CPU之间的差异,因此解决跨平台性的问题。
虽然提升了跨平台性,却因为中间码的存在降低了运行速度。Python如何解决这一问题呢?Python在下一次执行时,会检查源代码文件(*.py)文件与字节码文件(*.pyc)的时间戳,如果时间戳一致,说明源代码没有修改,那么就会跳过对源代码的编译过程而直接加载字节码进入虚拟机执行。如果时间戳不一致,才会重新编译。而字节码的执行相对较快,这样就大大缩短了项目运行前的准备时间。
__pycache__目录是Python解释器在运行程序时自动生成的缓存目录。
当Python解释器执行一个模块文件(.py文件)时,
它会将编译后的字节码存储在__pycache__目录中,以便下次执行相同的模块时可以更快地加载。
__pycache__目录的名称与源代码文件的名称相对应,但是以".pyc"作为文件扩展名。
例如,如果有一个名为"example.py"的源代码文件,那么对应的编译后的字节码文件将是"example.pyc",并存储在__pycache__目录下。你点进去之后就能发现对应关系。
.pyc文件就是字节码文件
使用__pycache__目录的主要目的是提高Python程序的执行性能。由于字节码已经被预先编译并存储在磁盘上,下次执行程序时可以直接加载字节码,而不需要重新解析源代码文件。这种方式可以减少启动时间,提高程序的整体性能。
__pycache__是可选的,它只在Python解释器认为需要缓存字节码时才会被创建。在一些情况下,如只执行一次的脚本或没有权限创建目录时,Python解释器可能不会生成__pycache__目录。
当 解释器执行一个模块时,它会首先检查是否存在对应的
.pyc
文件。如果存在,并且.pyc
文件的时间戳比源代码文件(.py 文件)新,那么解释器将直接加载该.pyc
文件,而不重新编译源代码。__pycache__ 目录是 Python 3 引入的。每个包或模块的 __pycache__ 目录都位于相应的包或模块所在的目录下。如果你有一个名为 my_module.py 的模块,那么它的编译后的字节码文件 my_module.pyc 将存储在与该模块同级的 __pycache__ 目录中。
__pycache__目录和.pyc文件是由 Python 解释器自动生成和管理的,一般你不需要手动操作或修改这些文件(说白了平常还是不用搭理)。在一些情况下,你可以删除__pycache__目录或对应的.pyc文件,它们会在下次执行相关模块时自动重新生成。
最后修订时间:2024年3月27日10:36:41
相关链接
python项目文件夹中__pycache__文件夹是干嘛的? - 知乎__pycache__目录是 Python解释器在运行程序时自动生成的缓存目录。当Python解释器执行一个模块文件(.py文件)时, 它会将编译后的字节码存储在__pycache__目录中, 以便下次执行相同的模块时可以更快地加载。 __p…https://zhuanlan.zhihu.com/p/686190341【Python】__pycache__文件夹是什么东西? - 知乎1. 概述在Python工作目录下,如果执行某文件后经常会自动生成一个__pycache__文件夹。如图1所示,当执行demo.py文件以后,在根目录和package文件夹下面都自动生成了__pycache__文件夹。这个__pycache__文件夹是什…https://zhuanlan.zhihu.com/p/476772186
完结撒花
又是这些有的没的?