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
猜你喜欢
- 变量(Variable)可以看成一个小箱子,专门用来“盛装”程序中的数据。每个变量都拥有独一无二的名字,通过变量的名字就能找到变量中的数据。
- 在一些项目中, 我们会使用json 来将字符串转为结构体,但是很多时候,这种结构体只会用一次,基本上只会用于反序列化, 对于这种只用到一次的
- 负责Web编写的前端人员,都清楚可以通过W3验证服务功能,来在线验证自己编写的XHTML代码是否正确,在验证期间,最容易出现的错误往往都是在
- UPDATE语句的速度更新查询的优化同SELECT查询一样,需要额外的写开销。写速度依赖于更新的数据大小和更新的索引的数量。没有更改的索引不
- 很多人不明白,学习这些冷门的函数基本上都用不到,或者说是什么多大用处,事实上,有是有很多用处的,比如今天给大家介绍的uuid模块,就能够生成
- Python字符串模糊匹配Python的difflib库中get_close_matches方法包含四个参数x:被匹配的字符串。words:
- open函数你必须先用Python内置的open()函数打开一个文件,创建一个file对象,相关的辅助方法才可以调用它进行读写。语法:fil
- 本文介绍了redis之django-redis的简单缓存使用,分享给大家,具体如下:自定义连接池这种方式跟普通py文件操作redis一样,代
- 一、前言Celery是一个基于python开发的分布式任务队列,而做python WEB开发最为流行的框架莫属Django,但是Django
- Python-类属性,实例属性,类方法,静态方法,实例方法类属性和实例属性#coding:utf-8class Student(object
- #BEGIN CONFIG INFO#DESCR: 4GB RAM, 只使用InnoDB, ACID, 少量的连接, 队列负载大#TYPE:
- 本文实例讲述了Python实现的服务器。分享给大家供大家参考,具体如下:python - 单进程服务器#coding=utf-8from s
- 虽然 prometheus 已有大量可直接使用的 exporter 可供使用,以满足收集不同的监控指标的需要。例如,node exporte
- javascript实现翻页效果:<html> <head> <title>上下翻页看 - aspxho
- 二维矩阵的transpose函数:不晓得该怎么起头,直接上干货。transpose()简单来说,就相当于数学中的转置,在矩阵中,转置就是把行
- 惭愧啊,今天写了个查找子串的Python程序被BS了…如果让你写一个程序检查字符串s2中是不是包含有s1。也许你会很直观的写下下面的代码:#
- 对所有数据进行整合与管理当你使用SQL Server 2008企业级的数据仓库平台时,你可以高效的操纵所有数据,并对其进行统一管理存储。◆合
- 前言这篇文章算是论坛PyTorch Forums关于参数初始化和finetune的总结,也是我在写代码中用的算是“最佳实践”吧。最后希望大家
- 摘要在这篇文章里,我将以反模式的角度来直接讨论Django的低级ORM查询方法的使用。作为一种替代方式,我们需要在包含业务逻辑的
- 目录安装基本操作打开图像转换格式展示图片剪裁合并缩略图旋转滤镜二次创作画线文字总结文 | 豆豆来源:Python 技术「ID: python