python-文件处理
1,文件处理
1,三元运算
三元运算又称三目运算,是对简单的条件语句的缩写,如:
1 if 条件成立: 2 val =1 3 else: 4 val = 2 5 6 换成三元运算: 7 8 val =1 if 条件成立 else 2 9 10 a=val =1 if 条件成立 else 2 11 print(a) 12 13 ## 14 1
2,文件处理
读,写,修改
1.0 r 读模式
1 f = open(file = '这里是文件路径', mode = 'r', encoding = 'utf-8') 2 data = f.read() 3 f.close() 4 5 # 这里file后面冒号里面是文件路径 6 # mode = r :表示文本只读模式,可以改为其他权限 7 # encoding...这里是以前原文件是什么编码写入的,现在以什么编码读出 8 # f.read()表示读取文件 9 # f.close()关闭文件
1.1 rb 二进制读模式
适用于不知道原文件的编码,但是想将文件以二进制编码展示出来,这时读出来的文件则为二进制文件,而此模式一般用于读取网络传输的文本,图片,视频。
注意,它在读写的时候是以bytes类型读写的,因此获得的是一个bytes对象而不是字符串。在这个读写过程中,需要自己指定编码格式。
在使用带b的模式时一定要注意传入的数据类型,确保为bytes类型。
1 f = open('file_test', mode = 'rb') 2 data = f.read() 3 print(data) 4 5 # b'xe6x81xadxe5x96x9cxe4xbdxa0xe8xafxbbxe5x87xbaxe6x9dxa5xe4xbax86 xe6x88x91xe5xb0xb1xe6x98xafxe5xa4xa7xe5xb8x85xe5x93xa5xe4xb8x80xe6x9ex9a ' 6 # 这里是以这种格式显示出来。
1.2 循环文件 for
对于很大的文件,为了不一下子将内存占满,可以采用循环文件的方法来读文件。即每次都只读一部份文件。
f = open("这里为文件的路径","r",encoding = "gbk") for line in f: print(line) f.close()
因为print每次打印出来都会自带换行,所以这个打印出来的数据之间都会多了一个行。
2.0 w 写模式
f = open('文件路径,若无此文件,则会创建', 'w', encoding='utf-8') f.write('这里是写入文件的内容') f.close() #写入的内容是unicode字符串类型,内部会根据encoding转换为制定编码的 01101010101,即:字节类型
2.1 wb 二进制写文件
f = open('文件路径,若无此文件,则会创建', 'wb') f.write('这里是写入文件的内容',encode='gbk') f.close()
注意
对于w,着重于创建,而不是修改,所以重复在一个文件里面重复进行写入操作,会直接先清空原文件内容,然后重新写入
wb,写入时需要直接传入以某种编码的0100101,即:字节类型
w 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010
3.0 a ab 追加模式
将内容追加到文件尾部。
1 f = open('file_test', 'a',encoding='gbk') 2 f.write(' 这个是新添加进来的内容') 3 f.close() 4 5 f = open('file_test', 'ab') 6 f.write(' 这个是新添加进来的内容'.encode('gbk')) #注意这里后面是一个点号 7 f.close()
4.0 混合操作
r+: 读写模式,先读后写,以读的模式打开,支持追加内容
写读模式没有什么作用 w+: 写读模式,先写后读,以写(创建)的模式打开,先清空原有内容,相比于w模式,只是支持了一个读功能,且还只能读写已经写入的新内容
1 f = open('file_test02', 'r+', encoding='gbk') 2 f.write('这个是混合模式了 你好呀1 你好呀2 你好呀3') 3 data = f.read() 4 print(data) 5 f.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #1 问:为什么这样子? 2 3 这是硬盘的存储原理导致的,当你把文件存到硬盘上,就在硬盘上划了一块空间,存数据,等你下次打开这个文件 ,<br>seek到一个位置,每改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上不会整体向后移。<br>所以就出现 当前这个情况 ,你想插入,却变成了会把旧内容覆盖掉。 4 5 #2 问:但是人家word, vim 都可以修改文件 呀,你这不能修改算个什么玩意? 6 7 我并没说就不能修改了,你想修改当然可以,就是不要在硬盘上修改,把内容全部读到内存里,<br>数据在内存里可以随便增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全部覆盖掉。<br>vim word等各种文本编辑器都是这么干的。 8 9 #3 问:说的好像有道理,但你又没看过word软件的源码,你凭什么这么笃定? 10 11 哈哈,我不需要看源码,硬盘 的存储原理决定了word必须这么干 ,不信的话,<br>还有个简单的办法来确认我说的,就是用word or vim读一个编辑一个大文件 ,至少几百MB的,你 会发现,<br>加载过程会花个数十秒,这段时间干嘛了? cpu 去玩了?去上厕所啦? 当然不是,是在努力把数据 从硬盘上读到内存里。 12 13 # 4问:但是文件如果特别大,比如5个GB,读到内存,就一下子吃掉了5GB内存,好费资源呀,有没有更好的办法呢? 14 15 如果不想占内存,只能用另外一种办法啦,就是边读边改, 什么意思? 不是不能改么?是不能改原文件 ,<br>但你可以打开旧文件 的同时,生成一个新文件呀,边从旧的里面一行行的读,边往新的一行行写,<br>遇到需要修改就改了再写到新文件 ,这样,在内存里一直只存一行内容。就不占内存了。 但这样也有一个缺点,<br>就是虽然不占内存 ,但是占硬盘,每次修改,都要生成一份新文件,虽然改完后,可以把旧的覆盖掉,但在改的过程中,还是有2份数据 的。 16 17 # 5问:还有更好的方式 么? 18 19 有完没完? 没了。
5.0 文件操作的其他功能:tell,seek
①flush: f.flush, 将刚刚写入的文件从内存buffer里强制刷新到硬盘;
②readline: f.readline, 只读一行,遇到 or 为止;
③seek:f.seek( )把操作文件的光标移到指定位置
*注意:seek的长度是按字节算的(read 是按照字符来算的),字符编码存每个字符所占的字节长度不一样。
如‘我是你爸爸’用gbk存是两个字节一个字,用utf-8就是三个字节,因此以gbk打开时,seek(4)就把光标切换到“是”
但如果是utf-8,seek(4)会导致,拿到了是这个字的一部分字节,打印的话会报错,因为处理剩下的文本时发现用相应字节不能表示一个字符。
④seekable:f.seekable() ,判断文件是否可进行seek操作。
⑤tell:f.tell(), 返回当前文件操作光标位置。
⑥truncate: f.truncate(), 按指定长度截断文件。指定长度的话,就是从文件开头截定指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。
⑦writable: f.writable(), 判断文件是否可写。
6.0 with关键字
with关键字用于Python的上下文管理器机制。为了防止诸如open这一类文件打开方法在操作过程出现异常或错误,或者最后忘了执行close方法,文件非正常关闭等可能导致文件泄露、破坏的问题。Python提供了with这个上下文管理器机制,保证文件会被正常关闭。在它的管理下,不需要再写close语句。注意缩进。
1 with open('test.txt', 'w') as f: 2 f.write('Hello, world!')
with支持同时打开多个文件:
1 with open('log1') as obj1, open('log2','w') as obj2: 2 s=obj1.read() 3 obj2.write(s)
7.1 修改文件
占硬盘修改
f1 = open('file_test03', 'r', encoding='utf-8') f2 = open('file_test03.new', 'w', encoding='utf-8') old_str = '钱大发' new_str = '钱小发' for line in f1: if old_str in line: line = line.replace(old_str, new_str) # 这里是替换,将旧字符替换为新的字符。 f2.write(line) f1.close() f2.close()