什么是 Python 中的 __pycache__ 文件夹?
off999 2024-10-12 06:17 64 浏览 0 评论
当您开发一个独立的 Python 脚本时,您可能不会注意到目录结构有什么异常。然而,当项目变得越来越复杂时,您通常会决定将部分功能提取到额外的模块或包中。这时,您可能会发现源文件旁边突然出现了一个 __pycache__ 文件夹,而且似乎是随机出现的:
project/
│
├── mathematics/
│ │
│ ├── __pycache__/
│ │
│ ├── arithmetic/
│ │ ├── __init__.py
│ │ ├── add.py
│ │ └── sub.py
│ │
│ ├── geometry/
│ │ │
│ │ ├── __pycache__/
│ │ │
│ │ ├── __init__.py
│ │ └── shapes.py
│ │
│ └── __init__.py
│
└── calculator.py请注意,当多个子包相互嵌套时,__pycache__ 文件夹可能存在于项目目录树的不同层次。同时,包含 Python 源文件的其他包或文件夹可能不包含这个神秘的缓存目录。
注意:为了保持工作区的整洁,许多 Python IDE 和代码编辑器在开箱配置时都会隐藏 __pycache__ 文件夹,即使这些文件夹存在于您的文件系统中。
简而言之:它让导入 Python 模块变得更快
尽管 Python 是一种解释型编程语言,但它的解释器并不直接对 Python 代码进行操作,因为那样会非常慢。相反,当您运行一个 Python 脚本或导入一个 Python 模块时,解释器会将您的高级 Python 源代码编译成字节码,字节码是代码的中间二进制表示形式。
这种字节码能让解释器跳过重复的步骤,比如将代码编入抽象语法树并进行解析,以及在每次运行相同程序时验证其正确性。只要底层源代码没有改变,Python 就能重复使用中间表示,并立即准备执行。这样可以节省时间,加快脚本的启动速度。
请记住,虽然从 __pycache__ 加载编译过的字节码会使 Python 模块的导入速度更快,但这并不影响它们的执行速度!
为什么要使用字节码,而不是直接将代码编译成底层机器码?虽然机器码可以在硬件上执行,提供极致的性能,但它的可移植性和生成速度都不如字节码。
机器码是一组能被特定 CPU 架构理解的二进制指令,根据操作系统的不同,被封装成 EXE、ELF 或 Mach-O 等容器格式。相比之下,字节码提供了一个与平台无关的抽象层,编译速度通常更快。
Python 使用本地的 __pycache__ 文件夹来存储项目中导入模块的编译字节码。在随后的运行中,解释器将尝试从这些文件夹中加载模块的预编译版本,前提是它们与相应的源文件是最新的。请注意,只有在代码中导入模块而不是在终端中作为脚本执行时,才会触发这种缓存机制。
除了磁盘上的字节码缓存外,Python 还保留了一个内存中的模块缓存,您可以通过 sys.modules 字典访问它。它确保当您在程序的不同位置多次导入同一个模块时,Python 将使用已经导入的模块,而无需重新加载或重新编译。这两种机制共同作用,减少了导入 Python 模块的开销。
接下来,您将了解在导入模块时,Python 加载缓存字节码比编译源代码快多少。
从缓存加载模块的速度有多快?
缓存发生在幕后,通常不会被注意到,因为 Python 编译字节码的速度非常快。此外,除非您经常运行短时 Python 脚本,否则编译步骤与总执行时间相比仍然微不足道。尽管如此,如果没有缓存,如果您有很多模块并多次导入它们,那么与字节码编译相关的开销就会增加。
要测量缓存模块和未缓存模块的导入时间差,可以在 python 命令中传递 -X importtime 选项,或设置等效的 PYTHONPROFILEIMPORTTIME 环境变量。启用该选项后,Python 将显示一个表格,总结导入每个模块所需的时间,包括一个模块依赖于其他模块时的累计时间。
假设你有一个 calculator.py 脚本,它从本地 arithmetic.py 模块导入并调用了一个实用程序函数:
from arithmetic import add
add(3, 4)导入的模块只定义了一个函数:
def add(a, b):
return a + b如您所见,主脚本将 3 和 4 这两个数字的加法运算委托给了从算术模块导入的 add() 函数。
注意:即使你使用from..import语法,它只是将指定的符号导入到当前的命名空间中,Python将读取并编译整个模块。此外未使用导入也会触发编译。
第一次运行脚本时,Python编译并保存你导入的模块的字节码到一个本地的__pycache__文件夹中。如果这样的文件夹不存在,那么Python会继续之前自动创建一个。现在当您再次执行脚本时,只要您没有更改相关的源代码,Python就应该能找到并加载缓存的字节码。
__pycache__文件夹里面有什么?
__pycache__文件夹中包含了模块的缓存版本,这些版本以.pyc文件的形式存储。.pyc文件是Python字节码的二进制表示形式,它们包含了模块的编译后的形式。
Python何时创建缓存文件夹?
Python在导入模块时会自动检查是否需要创建__pycache__文件夹。如果Python解释器有权限在当前目录下创建文件夹,且该目录下有Python源代码文件,则Python会自动生成__pycache__文件夹并在其中存储相应的缓存版本。
什么操作会使缓存失效?
缓存版本的生成是根据源代码文件的修改时间和内容进行的。如果源代码文件发生了更改,Python将重新生成缓存版本。因此,以下操作将使缓存失效:
- 修改了源代码文件。
- 从一个Python版本切换到另一个Python版本。
- 在不同的操作系统上运行相同的代码。
删除缓存文件夹是否安全?
是的,删除__pycache__文件夹通常是安全的。Python会在需要时自动重新生成缓存版本。删除缓存文件夹可能会导致稍微延迟一点,因为Python需要重新编译源代码以生成新的缓存版本,但不会对代码的正确性产生任何影响。
如何递归删除所有缓存文件夹?
你可以使用操作系统提供的命令或Python的第三方库来递归删除所有的__pycache__文件夹。例如,在Unix/Linux系统上,你可以使用find命令:
find . -type d -name '__pycache__' -exec rm -r {} +
或者
import shutil
import os
def remove_pycache(folder):
for root, dirs, files in os.walk(folder):
for d in dirs:
if d == '__pycache__':
shutil.rmtree(os.path.join(root, d))
remove_pycache('.')
如何防止Python创建缓存文件夹?
如果你不希望Python创建__pycache__文件夹,你可以在运行Python脚本时设置环境变量PYTHONDONTWRITEBYTECODE为1。
export PYTHONDONTWRITEBYTECODE=1
或者
import sys
sys.dont_write_bytecode = True
如何将缓存存储在集中的文件夹中?
如果你希望将所有缓存文件存储在一个集中的文件夹中,而不是在每个模块所在的目录中创建__pycache__文件夹,你可以设置环境变量PYTHONDONTWRITEBYTECODE为一个特定的目录路径。
export PYTHONDONTWRITEBYTECODE=/path/to/cache/folder
缓存的.pyc文件里面是什么?
缓存的.pyc文件包含了模块的编译后的字节码。这些字节码是由Python编译器生成的,可以直接由Python虚拟机执行。
如何读取和执行缓存的字节码?
你可以使用Python的importlib模块来读取和执行缓存的字节码。以下是一个简单的示例:
import importlib.util
# Load cached bytecode
spec = importlib.util.spec_from_file_location("module_name", "/path/to/module.pyc")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# Use the module
module.some_function()
字节码能够混淆Python程序吗?
虽然缓存的字节码不是为了隐藏代码而设计的,但它们确实可以使源代码不易被直接阅读。然而,这并不等同于真正的代码混淆或加密。如果你需要确保代码的安全性,最好使用专门的代码混淆工具。
如何反汇编缓存的字节码?
你可以使用Python标准库中的dis模块来反汇编缓存的字节码。以下是一个示例:
import dis
# Disassemble cached bytecode
with open("/path/to/module.pyc", "rb") as f:
dis.dis(f.read())
结论
__pycache__文件夹是Python中用于存储模块缓存版本的特殊文件夹。它可以提高模块导入的速度,并且在大型项目中尤其有用。虽然删除缓存文件夹通常是安全的,但你也可以通过设置环境变量来控制Python是否生成缓存文件夹,以及它们的存储位置。最后,虽然缓存的字节码可以使源代码不易被直接阅读,但它们并不等同于真正的代码混淆或加密,如果需要确保代码的安全性,最好使用专门的工具。
相关推荐
- winxp安装盘(winxp系统安装)
-
xp系统安装步骤如下1、将下载的xp系统iso压缩包文件下载到C盘之外的分区,比如下载到D盘,右键使用WinRAR等工具解压到当前文件夹或指定文件夹,不能解压到C盘和桌面,否则无法安装;?2、解压之后...
- 现在的win11稳定了吗(win11稳定嘛)
-
windows10更稳定,由于win11刚刚推出没多久,稳定差不够好,兼容性也有待提升,无论是应用还是游戏都会遇到不明程度的问题,因此,在日常的使用过程中,我们还是应当以稳定性为优先,选择win10是...
- xp安装包下载到手机(xp系统安装包)
-
手机是基于ARM架构的处理器,而WindowsXP是基于x86架构的操作系统,因此无法直接在手机上安装WindowsXP。除非您的手机是使用Intel处理器,但这种情况非常罕见。如果您需要在手机上...
- 如何查看硬盘序列号(windows如何查看硬盘序列号)
-
1.打开开始菜单栏,输入【cmd】点击【确定】;2.在命令窗口依次输入【diskpart】-【listdisk】-【selectdisk0】;3.选好要查看的硬盘后,接着输入【detaildi...
- 虚拟机安装win7教程(虚拟机安装win7教程图解)
-
1.首先,下载并安装虚拟机软件,如VMwareWorkstation、VirtualBox等。2.打开虚拟机软件,创建一个新的虚拟机。3.在创建虚拟机的过程中,选择安装Windows7专业版的IS...
- 系统脱敏法的操作程序如何
-
系统脱敏疗法(systematicdesensitization)又称交互抑制法,是由美国学者沃尔普创立和发展的。这种方法主要是诱导求治者缓慢地暴露出导致神经症焦虑、恐惧的情境,并通过心理的放松状态...
- 闪迪u盘低级格式化工具(闪迪u盘格式化分配单元大小)
-
闪迪U盘格式化后速度变慢的可能原因及解决方法如下:文件系统问题:格式化时选择的文件系统类型可能会影响U盘的性能。常见的文件系统类型包括FAT32、NTFS和exFAT等。如果文件系统类型不合适,可能会...
- psd文件下载(psd格式下载网站)
-
1、在photoshop中,不能通过置入的方法来加载PSD文件,因为,通过置入的方法加载PSD文件,它是以合并图层的方法把PSD文件加入,这样,就失去了PSD文件的所有图层信息。 2、在文档中想...
- 宏碁官网下载win7系统(宏碁官方系统)
-
宏基笔记本win8系统换成win7步骤:1、更改bios设置,关闭“SecureBoot”功能,启用传统的“LegacyBoot”。2、制作u启动U盘启动盘,下载win7系统安装包3、设置U盘启动...
- 如何重装系统win7旗舰版32位
-
首先下载制作一个带系统的启动u盘,然后按以下步骤安装:1、首先关闭电脑上面的杀毒软件,2、进入bios选择u盘启动。3、插入启动u盘重新启动电脑4、进入pe系统镜像环节,选择要安装的系统(32位),然...
- 应用程序发生异常0xe0000008
-
先查看一下对应的软件是不是出现了损坏,也可以重装此软件。我们还可以尝试通过修改注册表来解决。按Win+R(或者在开始菜单搜索框输入“运行”)打开运行,然后输入“regedit”回车,打开注册表恢复原来...
- 笔记本连接wifi显示无法连接网络
-
笔记本电脑连接wifi时提示无法连接到这个网络1、打开电脑“控制面板”,点击“网络连接”,选择本地连接,右键点击本地连接图标后选“属性”,在“常规”选项卡中双击“Internet协议(TCP/IP)...
- windowsc盘清理大师(c盘清理大师怎么样)
-
C盘清理大师是一款流氓软件,可不是windows10里自带。在你的电脑上出现这个软件一般情况下可以证明你使用的系统是盗版的,系统采用的是网上流传的系统镜像制作的。在网上流传这些系统镜像文件...
- realtek没声音如何设置(realtek怎么调出来)
-
你给无线连接配IP地址呗第一步:下载驱动精灵软件。第二步:安装驱动精灵软件。1、在打开的驱动软件安装窗口,确定程序安装路径后,点击:一键安装;2、正在安装。第三步:更新驱动程序。1、安装非常迅速,已经...
- 腾达路由器手机端登录入口(腾达路由器手机端登录入口在哪)
-
腾达路由器使用192.168.0.1或tendawifi.com作为登录地址。登录管理员页面的步骤:1、手机连接到腾达路由器的wifi信号;2、在手机上打开浏览器,在地址栏输入192.168.0.1后...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
