linecache模块加载和缓存文件内容详解
作者:GanZiQim 发布时间:2022-09-23 20:00:45
linecache模块
接触到linecache这个模块是因为前两天读attrs源码的时候看到内部代码引用了这个模块来模拟一个假文件,带着一脸疑问顺便读了一下这个模块的源码,发现其实也就那么回事儿,代码不多,在这总结一下。
linecache模块可以读取文件并将文件内容缓存起来,方便后面多次读取。这个模块原本被设计用来读取Python模块的源代码,所以当一个文件名不在指定路径下的时候,模块会通过搜索路径(search path)来尝试读取文件。
接口
linecache模块的__all__参数其实只提供了getline/clearcache/checkcache三个接口,但实际上可以使用的不止这些,下面我会对所有接口逐个进行介绍。
linecache.getline(filename, lineno, module_globals=None)
获取指定文件的某一行,filename指定文件名、lineno指定行号、module_globals用于指定模块的上下文我也不知道怎么称呼,姑且称为上下文吧,最后一个参数其实到会传到linecache.updatecache()里,用于尝试使用__loader__加载文件,一般情况下不会用到最后一个参数,忽略即可。当行号小于一或大于文件最大行号时函数直接返回空字符串。
linecache.clearcache()
清空所有缓存,注意是所有。
linecache.checkcache(filename=None)
这个函数用于检查缓存,如果文件的大小或者修改时间有变化,会把文件原先的缓存删除,如果文件是懒加载的则保持不变。当filename为None时检查缓存中的所有文件。
以下是没写进模块__all__参数的接口。
linecache.lazycache(filename, module_globals)
对指定文件使用懒加载,启用懒加载成功的文件会在实际调用获取内容的接口时才将文件内容加载进内存,使用这个可以避免多余的文件IO。返回值为一个布尔值,当懒加载成功时返回True,如果文件内容已经实际加载进内存或者加载失败则返回False。
这个函数的module_globals参数是必填的,其实就是传入要加载文件对应模块的上下文。比如加载linecache模块,则传入linecache.__dict__或者vars(linecache)(目前只想到这两种方法,当然你要自己构建一个字典传进去也是可以的)。然后函数会根据上下文获取__loader__的get_source函数保存到缓存中。这个函数是在Python3.5后新增的。
linecache.updatecache(filename, module_globals=None)
这个函数是整个模块的核心,用于更新文件缓存并返回文件内容。函数中间任何一个环节出错了会返回一个空列表。
对于普通文件,内部使用tokenize.open()函数用于打开文件,检测文件的编码并使用检测到的编码打开文件,如果缺失编码默认使用UTF-8。如果给定路径无法打开文件则使用sys.path指定的路径尝试加载。如果文件内容的最后一行不带\n,会自动在最后一个字符加上\n。
对于懒加载的文件,则调用懒加载时保存的get_source函数获取文件内容。
注意:linecache在打开文件之后使用readlines一次性加载所有文件内容,所以在文件很多或者文件太大时会出现问题,所以还是应该谨慎使用。
linecache.getlines(filename, module_globals=None)
获取文件所有内容,如果文件尚未加载或者是懒加载,会调用linecache.updatecache()加载文件内容,如果出现MemoryError则清空缓存。linecache.getline()其实内部就是调用了这个函数。
linecache.cache
这是一个字典,所有文件的缓存就存在这里面。字典的Key是你读取时传入的filename,Value是一个保存了文件大小、修改时间、内容、名字的元组,当文件为懒加载时则是对应__loader__的get_source函数。
总结
Python标准库内置了很多基础模块,平时不会注意到,但是总有一些别的代码会依赖到这些基础设施,像标准库里的pdb和traceback都有用到linecache模块。这里面其实有不少代码是能加以利用的,平时多多读源码,会有惊喜的。
来源:http://blog.csdn.net/jy692405180/article/details/78604327


猜你喜欢
- 1. 准备工作下载源码包wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.b
- zip()的作用先看一下语法:zip(iter1 [,iter2 [...]]) —> zip objectPython的内置help
- 1.先引入switchery.css 和 switchery.js2.绘制 checkbox按钮 : a.静态页面写法 未选中时
- 运行MySQL Server 5.0安装程序“setup.exe”,出现如下界面: 安装向导启动,按“Next”继续:
- 1)忘记在 if , elif , else , for , while , class ,def 声明末尾添加 :(导致 “SyntaxE
- 废话不多说。直接上代码:sock_post.php:<?phpfunction sock_post($url, $data='
- 前言最近网站从HTTPS转为HTTP,更换了网址,旧网址做了301重定向,折腾有点大,于是在百度站长平台提交网址,不管是主动推送还是手动提交
- SQL2000的SA密码不能更改的解决方法,在更改sa的密码出现下面的错误:Error 21776: [SQL-DMO] The name
- 由用户指定需要扫描的盘符或目录,输入需要查找的文件或者文件夹名称(不包含中文名称)代码:# encoding=utf-8import os.
- 开发需求python 3.7+pygame 1.9+演示项目地址https://github.com/Mr-han11/PythonSupe
- AES加密方式有五种 : ECB, CBC, CTR, CFB, OFB从安全性角度推荐cbc算法windows 下安装 : pip ins
- 这篇论坛文章(赛迪网技术社区)详细的介绍了在MySQL中使用GRANT语句增添新用户的具体步骤,更多内容请参考下文…&
- 最近,我们老大要我写一个守护者程序,对服务器进程进行守护。如果服务器不幸挂掉了,守护者能即时的重启应用程序。上网Google了一下,发现Py
- 在数字图像处理中,针对不同的图像格式有其特定的处理算法。所以,在做图像处理之前,我们需要考虑清楚自己要基于哪种格式的图像进行算法设计及其实现
- 数据结构和算法算法:解决问题的方法和步骤评价算法的好坏:渐近时间复杂度和渐近空间复杂度。渐近时间复杂度的大O标记:- 常量时间复杂度 - 布
- 一、引言生成数据库表有下面的三种方式:代码生成。程序包管理器控制台迁移。命令行迁移。下面分别介绍上面的三种方法。二、具体示例1、代码生成在程
- 前言众所周知在Python 中常用的数据类型bool(布尔)类型的实例对象(值)就两个,真和假,分别用True和False表示。在if 条件
- 一、集中式vs分布式1.Subversion属于集中式的版本控制系统集中式的版本控制系统都有一个单一的集中管理的服务器,保存所有文件的修订版
- 本文实例讲述了PHP单例模式用法。分享给大家供大家参考,具体如下:<?phpclass db { public $conn
- 这两条是关于IE环境中的CSS的。不要使用import引入CSS,可以避免内容的无样式瞬间(FOUC)问题。不要把样式的link放到页面后(