python linecache读取过程
最近使用Python编写日志处理脚本时,对Python的几种读取文件的方式进行了实验。其中,linecache的行为引起了我的注意。
Python按行读取文件的经典方式有以下几种:
with open('blabla.log', 'r') as f:
for line in f.readlines():
## do something
with open('blabla.log', 'r') as f:
for line in f:
## do something
with open('blabla.log', 'r') as f:
while 1:
line = f.readline()
if not line:
break
## do something
以上几种方式都不支持对于文件按行随机访问。在这样的背景下,能够支持访直接访问某一行内容的linecache模块是一种很好的补充。
我们可以使用linecache模块的getline方法访问某一具体行的内容,官方文档中给出了如下用法:
>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
在使用过程中我注意到,基于linecache的getline方法的日志分析会在跑满CPU资源之前首先占用大量内存空间,也就是在CPU使用率仍然很低的情况下,内存空间就会被迅速地消耗。
这一现象引起了我的兴趣。我猜测linecache在随机读取文件时,是首先依序将文件读入内存,之后寻找所要定位的行是否在内存当中。若不在,则进行相应的替换行为,直至寻找到所对应的行,再将其返回。
对linecache代码的阅读证实了这一想法。
在linecache.py中,我们可以看到getline的定义为:
def getline(filename, lineno, module_globals=None):
lines = getlines(filename, module_globals)
if 1 <= lineno <= len(lines):
return lines[lineno-1]
else:
return ''
不难看出,getline方法通过getlines得到了文件行的List,以此来实现对于文件行的随机读取。继续查看getlines的定义。
def getlines(filename, module_globals=None):
"""Get the lines for a file from the cache.
Update the cache if it doesn't contain an entry for this file already."""
if filename in cache:
return cache[filename][2]
else:
return updatecache(filename, module_globals)
由此可见,getlines方法会首先确认文件是否在缓存当中,如果在则返回该文件的行的List,否则执行updatecache方法,对缓存内容进行更新。因此,在程序启动阶段,linecache不得不首先占用内存对文件进行缓存,才能进行后续的读取操作。
而在updatecache方法中,我们可以看到一个有趣的事实是:
def updatecache(filename, module_globals=None):
"""Update a cache entry and return its list of lines.
If something's wrong, print a message, discard the cache entry,
and return an empty list."""
## ... 省略...
try:
fp = open(fullname, 'rU')
lines = fp.readlines()
fp.close()
except IOError, msg:
## print '*** Cannot open', fullname, ':', msg
return []
if lines and not lines[-1].endswith('\n'):
lines[-1] += '\n'
size, mtime = stat.st_size, stat.st_mtime
cache[filename] = size, mtime, lines, fullname
return lines
也就是说,linecache依然借助了文件对象的readlines方法。这也给了我们一个提示,当文件很大不适用readlines方法直接获取行的List进行读取解析时,linecache似乎也并不会成为一个很好的选择。
python linecache读取过程的更多相关文章
- python linecache模块读取文件的方法
转自: python linecache模块读取文件 在Python中,有个好用的模块linecache,该模块允许从任何文件里得到任何的行,并且使用缓存进行优化,常见的情况是从单个文件读取多行. l ...
- Delphi中使用python脚本读取Excel数据
Delphi中使用python脚本读取Excel数据2007-10-18 17:28:22标签:Delphi Excel python原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...
- 【原创】控制perl和python脚本执行过程中脚本文件是否关闭的方法
引子 跟踪perl和python脚本对文件的访问,实际过程中,perl和python解析器在解析完脚本后,直接关闭了 脚本文件,在进程中查询不到是访问文件的脚本文件名称. shell.perl和pyt ...
- python配置文件读取
在代码实现的过程中,我们经常选择将一些固定的参数值写入到一个单独的配置文件中.在python中读取配置文件官方提供了configParser方法. 主要有如下方法(找官文): (这家伙很懒,直接复 ...
- Linux环境下Python的安装过程
Linux环境下Python的安装过程 前言 一般情况下,Linux都会预装 Python了,但是这个预装的Python版本一般都非常低,很多 Python的新特性都没有,必须重新安装新一点的版本,从 ...
- python下读取excel文件
项目中要用到这个,所以记录一下. python下读取excel文件方法多种,用的是普通的xlrd插件,因为它各种版本的excel文件都可读. 首先在https://pypi.python.org/py ...
- Python逐块读取大文件行数的代码 - 为程序员服务
Python逐块读取大文件行数的代码 - 为程序员服务 python数文件行数最简单的方法是使用enumerate方法,但是如果文件很大的话,这个方法就有点慢了,我们可以逐块的读取文件的内容,然后按块 ...
- python专题-读取xml文件
关于python读取xml文章很多,但大多文章都是贴一个xml文件,然后再贴个处理文件的代码.这样并不利于初学者的学习,希望这篇文章可以更通俗易懂的教如何使用python 来读取xml 文件. 什么是 ...
- 【Netty源码分析】数据读取过程
首先客户端连接到服务端时服务端会开启一个线程,不断的监听客户端的操作.
随机推荐
- 【转载】#457 Converting Between enums and their Underlying Type
When you declare an enum, by default each enumerated value is represented internally with an int. (S ...
- ArcGIS Server Java 9.3 REST API的中文查询问题的解决方案
[2009.2.18补注]这个问题在SP1 for Linux中修复,SP1 for Windows下问题更加严重,如果打了SP1 for Windows,还想使用REST服务,就必须使用Linux或 ...
- UVALive 6261 Jewel heist
题意:珠宝大盗Arsen Lupin偷珠宝.在展厅内,每颗珠宝有个一个坐标为(xi,yi)和颜色ci. Arsen Lupin发明了一种设备,可以抓取平行x轴的一条线段下的所有珠宝而不触发警报, 唯一 ...
- HDU 6178 Monkeys
题意:给出一棵 N 个节点树,上面有 K 个猴子,然后竟可能删边,但是每一只猴子必须有直接相邻的猴子与之相邻.求最少剩下几条边. 分析:一条边可以用两只猴子站,这样的一条点对,越多越好,如果是ans个 ...
- Gym 101308I Inspection
题意: 用最少的路径,覆盖掉所有的边,(点可以重复): 不是用最小路径覆盖,最小路径覆盖是覆盖点: 分析: 建图:入度<出度,说明这是个起点,从这里出发,入度>出度,说明从这里结束: 先找 ...
- CSP
CSP(Content-Security-Policy): 内容安全策略 作用: .限制资源获取 .报告资源获取越权 限制方式: .default-src限制全局 跟链接请求有关的东西,限制他 ...
- 【转】同步的HttpClient使用详解
http://blog.csdn.net/angjunqiang/article/details/54340398 背景 服务端以及客户端在开发过程中不可避免的会使用到网络请求,网络请求可以使用Jav ...
- SSH原理与远程登陆
本文转载自:http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html 在<计算机系统结构>课程实验中接触到SSH,本文对SS ...
- 封装方法到对象(javascript)
/*! * artDialog 5 * Date: 2012-03-21 * http://code.google.com/p/artdialog/ * (c) 2009-2012 TangBin, ...
- JS JavaScript深拷贝、浅拷贝
浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也会相应改变. 深拷贝:开辟了一块新的内存存放地址和地址指向的对象,原地址的任何对象改变了,深拷贝出来的对象不变. 浅拷贝数 ...