7.8文件处理补充及函数简介
文件处理补充
1. r+
with open(r'test',mode='r+',encoding='utf-8') as f: print(f.readable()) # True print(f.writable()) # True print(f.readline()) f.write('添加文字')
可读可写
2. w+
with open(r'test',mode='w+',encoding='utf-8') as f: print(f.readable()) # True print(f.writable()) # True print(f.readline()) f.write('添加文字')
可读可写,一写就清空文件内容
3. a+
with open(r'test',mode='a+',encoding='utf-8') as f: print(f.readable()) # True print(f.writable()) # True print(f.readline()) f.write('添加文字')
可读可写,光标在文件末尾,读不出内容,写内容不会清空原文件内容
4.read(括号中可添加参数)
with open(r'test','rt',encoding='utf-8') as f: print(f.read(3))
只有在rt模式下,read内的数字,表示的是想要读取的字符的个数。除此之外,数字表示的都是想要读取的字节数
with open(r'test','rb') as f: res = f.read(3) # 读的是三个字节bytes print(res) print(res.decode('utf-8'))
5.文件内光标的移动
seek():括号中包含两个参数,offset和whence,表示相对偏移量 和 光标移动的位数
whence:
0:表示参照文件的开头,光标移到开头,t和b模式都可以使用
with open(r'test','rt',encoding='utf-8') as f: print(f.read(3)) f.seek(3,0) # seek移动都是字节数,表示光标从文件开头移动三字节 print(f.read(3))
1:表示参照光标所在的当前位置,只能在b模式下使用
with open(r'test','rb') as f: print(f.read(3).decode(encoding='utf-8')) # 为进制形式,需要解码 f.seek(3,1) # seek移动都是字节数,表示光标从当前位置移动三字节 print(f.read(3).decode(encoding='utf-8'))
2:表示参照文件的末尾,光标移动到末尾,只能在b模式下使用
with open(r'test','rb') as f: print(f.read(3).decode(encoding='utf-8')) # 为进制形式,需要解码 f.seek(-3,2) # seek移动都是字节数,表示从文件末尾向左移(-3)三字节 print(f.read(3).decode(encoding='utf-8'))
补充:添加内容
with open(r'test','r+',encoding='utf-8') as f: f.seek(6,0) f.write('写')
不是添加内容,而是替换
6.实时监测文件内容变化
写日志
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个亿的工资\n'%res)
打印文件新增的内容
with open(r'test01.txt','rb') as f: f.seek(0,2) # 先将光标移动到文件末尾 while True: res = f.readline() print(f.tell()) # 查看光标移动了多少位 bytes if res: print("新增的文件内容:%s"%res.decode('utf-8')) # 有数据就说明有人操作当前文件 else: print('暂无其他人操作该文件') # 说明文件没有被任何人操作
7.截断文件
with open(r'test','a',encoding='utf-8') as f: f.truncate(6) # 接收的字节的长度(整型),保留0~6字节数,后面的全部删除(截断)
8.修改文件
第一种:
步骤:1.先将数据由硬盘读到内存(读文件)
2.在内存中完成修改(字符串的替换)
3.再覆盖原来的内容(写文件)
with open(r'test02.txt','r',encoding='utf-8') as f: data = f.read() with open(r'test02.txt','w',encoding='utf-8') as f: res = data.replace('egon','jason') f.write(res) print(res)
优点:任意时间硬盘上只有一个文件,不会占用过多硬盘空间
缺点:当文件过大的情况下,可能会造成内存溢出
第二种:
步骤:1.创建一个新文件
2.循环读取老文件内容到内存进行修改,将修改好的内容写到新文件中
3.将老文件删除,将新文件的名字改成老文件名
import os with open(r'test02.txt','r',encoding='utf-8') as read_f,\ open(r'test02.swap','a',encoding='utf-8') as write_f: for line in read_f: new_line = line.replace('jason','egon') write_f.write(new_line) os.remove('test02.txt') # 删除老文件 os.rename('test02.swap','test02.txt') # 将新文件名改成老文件名
优点:内存中始终只有一行内容,不占内存
缺点:在某一时刻硬盘上会同时存在两个文件
函数
定义:函数就是工具,并且函数必须先定义后调用(函数名+括号)
命名规则:函数名的命名规则跟变量名命名规则一模一样
如何在没有len()关键字的情况下统计s = 'hello'的字符个数
s = 'hello' n = 0 for i in s: n += 1 print(n)
可以把这个for循环方法定义为一个函数,要用就直接拿
def my_len(): s = 'hello' n = 0 for i in s: n += 1 print(n) my_len() # 可以通过函数名+括号,找到函数体所对应的代码并执行
函数体代码定义截断只检测语法,不执行代码
def my_len(): sdsdsfxcsfx85ds sdsf8598 乱打的 乱打 # 运行不会报错,只有调用这个函数才会执行里面的代码 # my_len() # 报错