Python 创建、读取和写入文件以及yield关键字- 千月的python linux 系统管理指南学习笔记(14)

来源:互联网 发布:qq飞车风火轮数据 编辑:程序博客网 时间:2024/06/05 06:44

无论是日志文件还是配置文件都是我们日常运维中常见的类型,学习处理文件的关键是学会如何处理文本数据。Python 包含一个称为 file 的内建类型,可以用来处理文件。

创建文件对象
为了读取一个现有的文件,我们需要创建一个新的文件对象,以用来对文件进行交互。
open( ) 创建一个文件对象
open( "文件名","模式",[缓冲区大小] ) #以指定模式对文件交互
最普通的模式为 “r" 读模式 为默认模式,还有 ”w“ 写模式 ”a“ 附加模式 ”b“ 二进制模式

我们先建立一个文件作为交互对象。



read() 读取文件内容
这个读取的方式是,从文件头读取到文件尾。 后面我们还会详细讨论读文件的方法。


write() 将文本写入文件
close() 将文件关闭
这个写入文件,是覆盖写入,无论之前有什么内容都会被覆盖掉。
而且我们可以看例子,在写入完毕后必须使用 close() 将文件关闭。否则文件并无内容。
当你要写入文件,数据并不会直接写入文件中,而是首先写入到缓冲区,
等到缓冲区满或者刷新时,才将缓冲区的数据写入到文件中,
如果不这样做会对磁盘 I/O 产生大量占用,降低读写效率。
毕竟写入缓冲区比写入硬盘可快多了。


读取文件对象
read() 读取文件内容
文件对象.read([size] ) #读取全部或指定长度的文件
我们读取文件,主要是为了取得文件内的数据。我们先准备一个文件。

这个例子看了会有几个问题:
首先 \n 是换行符,并没有翻译成换行,而是如实的写了出来。当然用 print 就没这问题。
其次,我们在 read() 读取了一次后,再次 read() 无法获得任何字符。那是因为read是依靠指针来进行判断是否到了文件尾。 read() 一次后,指针到了文件尾,再 read() 自然毫无返回。我们使用seek(0)将指针指回文件头。再次读取就可以看到内容了,而2次 read(10)返回不同,更是证明了指针的存在。

readline() 读取一行文件内容
文件对象.readline( [size] ) #读取全部或指定长度的一行文件
readlines() 按行的方式读取全部文件内容
这两个命令很相似,readline 仅读取一行,而 readlines 将全部文件读入并且组成一个按行分隔的列表。

我们在工作中希望以行为单位处理文件的时候,一般情况下使用 readlines 。因为readlines 可以直接被 for ... in ... 结构使用。
我们尝试给文件的每一行前面加上一个 #


写入文件对象
write() 将文本写入文件
write() 写入文件在之前的创建环节已经研究过了,不再赘述。
当然如果你要在python环境下写小说可以用 write() 慢慢写,虽然文本编辑器会是更好的选择。我们在运维工作中更多的还是基于行的写入操作。比如固定格式的 Log 日志,统计报表等。进行这样的操作我们引入 writelines()
writelines() 将文本序列写入文件
文件对象.writelines( 文本序列 ) #将文本序列写入文件
尴尬的是虽然 writelines 直译过来是 写入行,但是事实上并不会为每个元素自动换行,我还是要加入 \n 的。或许叫做写入元素更合适。

首先我们定义了一个叫 range1的函数,这个函数里面带有一个循环,而这里使用 yield这个关键字,使这个函数变成了一个 generator(生成器),从而使 writelines 调用的时候可以使用其迭代属性,而迭代结束时抛出的 StopIteration 异常,可以直接被捕获,终止 writelines 。
如果感到理解起来有些吃力,可以自行搜索下 yield 这个关键字。在运维过程中会经常用到,比如打开一个巨大的文件,又怕内存占用不可预测而产生问题,可以通过 yield 避免。

举一个简单的 yield 读取文件的例子
主要是避免一次打开大文件而引起的未知内存占用问题。我们分块读取。

我们定义了一个 read_file 函数,参数是文件路径。BLOCK_SIZE是定义了一次读取的字符量。
在循环里我们使用了 yield 使函数变为一个生成器。每次只读取 10 字节。
我们在引用的时候也要使用 for ... in ... 来输出。为了清楚的看到效果,我用 print 来进行输出。确实每次读取10字节。这样避免一次读取全部文件而对内存造成无意义的过高占用,使得内存占用从未知变量变为已知常量。

阅读全文
0 0
原创粉丝点击