Python3.7之文件操作
一、基本操作
基于字符的读取(r),写入(w)与追加(a)
1.mode=\’r\’
f = open(file=\'文件读取.txt\', mode=\'r\')
print(f.read())
2.mode=\’w\’
f = open(file=\'文件写入.txt\', mode=\'w\')
f.write(\'谢欣然 湖北 保密 保密\')
write模式下,将数据写入文件时,文件原有数据会被清空,即创建一个新文件以写入数据
3.mode=\’a\’
f = open(file=\'文件写入.txt\', mode=\'a\')
f.write(\'xxr 湖北 保密 保密\')
在文件close之前,写入的数据暂时存在内存里,文件close之后才将数据追加到硬盘上。若不close文件,也可用flush刷新硬盘上的文件,此时新加入的数据已显示在原来的文件数据之后。
4.打开文件时会出现的编码错误
报错:UnicodeDecodeError: \’gbk\’ codec can\’t decode byte 0xac in position 9: illegal multibyte sequence
原因:mac/linux系统编码为utf-8,windows系统编码为gbk,在Windows上打开mac/linux电脑传过来的文件时,会出现文件编码错误
解决方案:此时在代码开头加上# – – utf-8 – -并没有用,需在open(file)中加上编码方式encoding=utf-8
错误代码:
f = open(file=\'文件错误.txt\', mode=\'r\')
print(f.read())
正确代码:
f = open(file=\'文件错误.txt\', mode=\'r\', encoding=\'utf-8\')
print(f.read())
二、区分read(), readline(), readlines()
1.read([size])
从文件的开始位置读取size个字节的内容,如果read()中没有带参数的话那么就是读取至整个文件结束,所以比较适合小型文件,把读取的东西放在一个字符串中,返回的是一个字符串。
f = open(file=\'文件读取.txt\', mode=\'r\')
print(f.read(10))
print(\'--------分隔符--------\')
print(f.read())
f.close()
\'\'\'
输出:
--------分隔符--------
广州 173 50
乔亦菲 广州 172 52
罗梦竹 北京 175 49
刘诺涵 北京 170 48
岳妮妮 广州 177 54
贺婉萱 广州 174 52
叶梓萱 上海 171 49
黑姑娘 河北 168 48
\'\'\'
2.readline()
readline读取一行的意思,利用循环可以一行一行的读取,比较适合大型文件成千上百行的那种,此方法返回一个字符串对象。
f = open(file=\'文件读取.txt\', mode=\'r\')
print(\'--------分隔符--------\')
lines = f.readline()
while lines:
print(lines.strip())
# print自带换行
# strip用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
lines = f.readline()
f.close()
\'\'\'
输出:
--------分隔符--------
Alex马大帅 广州 173 50
乔亦菲 广州 172 52
罗梦竹 北京 175 49
刘诺涵 北京 170 48
岳妮妮 广州 177 54
贺婉萱 广州 174 52
叶梓萱 上海 171 49
黑姑娘 河北 168 48
\'\'\'
3.readlines()
这个方法是读取文件的所有行,把结果保存在一个列表(list)中,每一行都作为列表的一个元素,不适合读取成千上万行的文件,因为可能会卡死也会比较占内存。但读取整个文件到一个迭代器方便我们遍历(即读取到一个list中,以供使用,比较方便)。
f = open(file=\'文件读取.txt\', mode=\'r\')
print(\'--------分隔符--------\')
print(f.readlines())
f.close()
\'\'\'
--------分隔符--------
[\'Alex马大帅 广州 173 50\n\', \'乔亦菲 广州 172 52\n\', \'罗梦竹 北京 175 49\n\', \'刘诺涵 北京 170 48\n\', \'岳妮妮 广州 177 54\n\', \'贺婉萱 广州 174 52\n\', \'叶梓萱 上海 171 49\n\', \'黑姑娘 河北 168 48\n\']
\'\'\'
补充:根据条件查询文件信息
输出:身高大于170,体重小于50的成员信息
f = open(file=\'文件读取.txt\', mode=\'r\')
for line in f:
line = line.split()
height = int(line[2])
weight = int(line[3])
if height > 170 and weight < 50:
print(line)
f.close()
\'\'\'
[\'罗梦竹\', \'北京\', \'175\', \'49\']
[\'叶梓萱\', \'上海\', \'171\', \'49\']
\'\'\'
三、文件操作的其他功能
1.seek(offset)
把操作文件的光标移动到指定位置,返回值为None,即无返回值。
offset:开始的偏移量,也就是代表需要移动偏移的字节数。
注意:seek的长度是按字节算的,字符编码存每个字符所占的字节长度不一样。如汉字,用gbk存是2个字节一个字,用utf-8就是3个字节一个字。只能按整长度截取,否则报错。
# 修改文件
f = open(\'文件写入.txt\', \'r+\')
# 注意r+的添加是从当前指针开始添加,所以要添加到尾部
# 一定要f.read()从头到尾读一遍,不然就是从头到为开始覆盖
f.seek(2)
f.write(\'小新\')
\'\'\'
此修改文件会对原文件进行覆盖,即插入后会覆盖之后的数据
\'\'\'
2.tell()
返回当前文件操作光标的位置
3.flush()
把文件从内存buffer里强制到硬盘。在文件close之前,写入的数据暂时存在内存里,文件close之后才将数据追加到硬盘上。若不close文件,也可用flush刷新硬盘上的文件,此时新加入的数据已显示在原来的文件数据之后。
4.os.rename与os.replace
关于Windows系统下,用os.rename替换文件时出现的坑:
import os
old_file = \'修改文件.txt\'
new_file = \'修改文件2.txt\'
f = open(file=old_file, mode=\'r\', encoding=\'utf-8\')
f_new = open(new_file, \'w\')
old_str = \'深圳\'
new_str = \'广州\'
for line in f:
if old_str in line:
line = line.replace(old_str, new_str)
f_new.write(line)
f.close()
f_new.close()
os.rename(new_file, old_file) # 此行错误
报错:FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。: \’修改文件2.txt\’ -> \’修改文件.txt\’
原因:Windows系统,在同一个文件夹内,无法命名一个相同文件名的文件。iOS与Linux可以直接重命名,并会替换掉之前的文件。
解决方案:将rename改为replace
5.占硬盘的方式修改文件
用占硬盘的方式修改文件可以不进行覆盖,进行整体修改。如word,vim,不在硬盘上修改,把内容全部读到内存里,数据可以在内存里增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全都覆盖掉。
old_file = \'修改文件.txt\'
new_file = \'修改文件2.txt\'
f = open(file=old_file, mode=\'r\', encoding=\'utf-8\')
f_new = open(new_file, \'w\')
old_str = \'深圳\'
new_str = \'广州\'
for line in f:
if old_str in line:
line = line.replace(old_str, new_str)
f_new.write(line)
f.close()
f_new.close()
此方法生成一个新文件“修改文件2”,存在硬盘里,若想覆盖原文件:
import os
old_file = \'修改文件.txt\'
new_file = \'修改文件2.txt\'
f = open(file=old_file, mode=\'r\', encoding=\'utf-8\')
f_new = open(new_file, \'w\')
old_str = \'深圳\'
new_str = \'广州\'
for line in f:
if old_str in line:
line = line.replace(old_str, new_str)
f_new.write(line)
f.close()
f_new.close()
os.replace(new_file, old_file)
6.sys argv[]
sys argv[]是一个从程序外部获取参数的桥梁,即从终端(命令行)获取参数。从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可以看作是一个列表,所以才能用[]提取其中的元素。 其第一个元素是程序本身,随后才依次是外部给予的参数。
import sys
print(sys.argv)
从Pycharm的Terminal终端输入输出结果:
\'\'\'
C:\Users\Administrator\Desktop\新建文件夹>python 4.py
[\'4.py\']
C:\Users\Administrator\Desktop\新建文件夹>python 4.py Hello world!
[\'4.py\', \'Hello\', \'world!\']
\'\'\'
7.open with告别文件开关繁琐操作
文件用open打开后就一定要关闭(close),而使用with打开就可以不需加上close。
原代码:
file = open(\'1.txt\', \'w\')
file.write(\'简单明了,省时省力\')
file.close()
改进后的代码:
with open(\'1.txt\', \'w\') as file:
file.write(\'简单明了,省时省力\')
open也可进行多个文件的同时打开:
with open(\'a.txt\',\'r\',encoding=\'utf-8\') as f,open(\'b.txt\') as f1:
f.write(\'简单明了,省时省力\')
f1.write(\'简单明了,省时省力\')