读写模式
‘r+’
-
可读; 文件不存在就报错 覆盖(从光标处向后覆盖,传多少内容就覆盖多少,并不是全部擦除)
with open(r'1.txt',mode='r+',encoding='utf-8') as f: print(f.readable()) print(f.writable()) print(f.readlines()) f.seek(0,0) f.write('HHHHH') with open(r'1.txt', mode='r+', encoding='utf-8') as f: print(f.readlines())
# 执行结果 True True ['This is a test. ', 'this is a test.'] ['HHHHHis a test. ', 'this is a test.']
'w+'
-
可读; 文件不存在就新建 覆盖('w+'模式打开文件的那一刻,文件已经被清除干净了) 只是比w多了一个‘可读’功能,但是由于清除,他的可读没什么实际效果
with open(r'1.txt',mode='w+',encoding='utf-8') as f: print(f.readable()) print(f.writable()) print(f.readlines()) f.seek(0,0) f.write('HHHH') with open(r'1.txt',mode='r',encoding='utf-8') as f: print(f.readlines())
# 执行结果 True True [] ['HHHH']
a+
-
可读可写; 文件不存在就新建; 'a+'模式打开文件,光标在文件尾部(seek也无法控制追加的位置,光标位置无论在哪,结果都是在末尾追加了)
with open(r'1.txt',mode='a+',encoding='utf-8') as f: print(f.readable()) print(f.writable()) print(f.readlines()) f.seek(0,0) f.write('HHHHH') with open(r'1.txt', mode='r', encoding='utf-8') as f: print(f.readlines())
# 执行结果 True True [] ['This is a test. ', 'this is a test.HHHHH']
光标移动
注意
-
在rt模式下 read内的数字 表示的是字符的个数;除此之外,数字表示的都是字节
''' 文件内容: This is a test. this is a test. ''' with open(r'1.txt','r',encoding='utf-8') as f: print(f.read(4))
# 执行结果 This
# 文本内容:这是一个测试 with open(r'1.txt','rb') as f: res = f.read(3) # 读的是三个字节bytes print(res) print(res.decode('utf-8'))
# 执行结果 b'xe8xbfx99' 这
f.seek(offset,whence)
seek移动都是字节数 offset:相对偏移量 光标移动的位数 whence: 0:参照文件的开头 t和b都可以使用 1:参照光标所在的当前位置 只能在b模式下用 2:参照文件的末尾 只能在b模式下使用
写日志
a模式下,指定文件内容的替换
import time res = time.strftime('%Y-%m-%d %X') with open(r'test01.txt','a',encoding='utf-8') as f: f.write('%s egon给jason发了1个亿的工资 '%res)
# 执行结果如下图
检测文件是否新增内容
思路:现将光标定位到末尾--通过readline检测是否有新内容
with open(r'1.txt','rb') as f: f.seek(0,2) while True: res = f.readline() if res: print(res.decode('utf-8'))
截断文件
f.truncate(3)
无论是否指定光标位置,都是从开头截取指定长度 3,剩下内容的都删除。
如果不指定长度,则从当前位置起,剩下的内容全删除。相当于从开头截至当前光标位置;
截完之后,光标回到开头
如果截之前光标定过位,那就回到这个定位
修改文件
方案一:覆盖
-
方案概述: 字符串拿到文件内容--修改后w模式覆盖到文件中
-
具体步骤: a.读文件(现将文件内容从硬盘读到内存) b.字符串替换(在内存中完成修改) c.写文件(覆盖原来的内容)
-
优点:任意时间,硬盘上只有一个文件,不会占用过多的硬盘空间 缺点:文件过大的情况下,可能会内存溢出
with open(r'1.txt', 'r', encoding='utf-8') as f: data = f.read() print(data) print(type(data)) with open(r'1.txt', 'w+', encoding='utf-8') as f: res = data.replace('I', 'You') f.write(res) f.seek(0, 0) print(f.read())
# 执行结果 I can fly. <class 'str'> You can fly.
方案二:新建文件
-
概述:读取老文件内容--修改后写入新文件--删除旧文件,重命名新文件
-
具体步骤: a.创建一个新文件 b.循环读取老文件到内存,将修改好的内容写道新文件 c.删除旧文件,重命名新文件
import os with open(r'1.txt','r',encoding='utf-8') as read_f, open(r'1.swap','a',encoding='utf-8') as write_f: print(read_f.read()) read_f.seek(0,0) for line in read_f: new_line = line.replace('I','You') write_f.write(new_line) os.remove('1.txt') os.rename('1.swap','1.txt') with open(r'1.txt','r',encoding='utf-8') as read_f: print(read_f.readlines())
# 执行结果 I can fly. I can fly. ['You can fly. ', 'You can fly.']
函数前戏
定义格式:def 函数名()
定义规则:
函数名的命名规则跟变量名一模一样 函数就是工具,并且函数必须先定义后调用(函数名+括号) 定义时只检测语法,不执行代码
使用:
可以通过变量名找到变量对应的值 同理:可以通过函数名+括号 找到函数体所对应的代码并执行