本章内容概要
1.文件内光标的移动
2.文件数据修改
3.函数简介
本章内容详细
1.文件内光标的移动
1.1 read(数字)
#在文本模式下read括号内的数字表示读取几个字符
with open(r'a.txt', 'r', encoding='utf8') as f:
data = f.read(3)
print(data) # a你好
在二进制模式下read括号内的数字表示读取几个字节(英文一个字节 中文三个字节)
with open(r'a.txt', 'rb') as f:
data = f.read(4)
print(data.decode('utf8')) # a你
1.2 代码控制光标移动
1.tell() 获取光标移动的字节数
with open(r'a.txt', 'r', encoding='utf8') as f:
data = f.read(3)
print(data) # a你好
print(f.tell()) # 7
2.seek(offset,whence)
offset 控制光标移动的位移量(字节)
whence 模式
0 基于文件开头移动多少字节
1 基于光标当前所在位置移动多少字符
2 基于文件末尾移动多少字节
1和2 只能在二进制模式下使用 0 无所谓
# 0 基于文件开头移动多少字节
with open(r'a.txt', 'r', encoding='utf8') as f:
data = f.read()
print(data) # a你好你好
f.seek(1,0)
print(f.read()) # 你好你好
1 基于光标当前所在位置移动多少字节
with open(r'a.txt', 'rb') as f:
data = f.read(4)
print(data.decode('utf8')) # a你
f.seek(-3, 1)
print(f.read().decode('utf8')) # 你好我他
2 基于文件末尾移动多少字节
with open(r'a.txt', 'rb') as f:
data = f.read()
print(data.decode('utf8')) # a你好我他
f.seek(-3, 1)
print(f.read().decode('utf8')) # 他
# 小练习:实现动态查看最新一条日志的效果
import time
with open('access.log', 'rb') as f:
f.seek(0, 2)
while True:
line = f.readline()
if len(line) == 0:
# 没有内容
time.sleep(0.5)
else:
print(line.decode('utf-8'), end='')
with open(r'access.log', 'a', encoding='utf8') as f:
f.write('新加入')
f.write('再加入')
2.文件数据修改
2.1 原理与方式
机械硬盘存储数据的原理
1.数据的修改 其实是覆盖写
2.数据的删除 占有态自由态
代码修改文件的方式
文件对应的是硬盘空间,硬盘不能修改对应着文件本质也不能修改,
那我们看到文件的内容可以修改,是如何实现的呢?
大致的思路是将硬盘中文件内容读入内存,然后在内存中修改完毕后再覆盖回硬盘
具体的实现方式分为两种:
1.覆盖写 :先读取文件内容到内存 在内存中完成修改 之后w模式打开该文件写入
2.重命名 :先读取文件内容到内存 在内存中完成修改 之后保存到另外一个文件中,再将原文件删除 将新的文件重命名为原文件
# 文件a.txt内容如下
张一蛋 山东 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
# 执行操作
with open('a.txt',mode='r+t',encoding='utf-8') as f:
f.seek(9)
f.write('<妇女主任>')
# 文件修改后的内容如下
张一蛋<妇女主任> 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
# 强调:
# 1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容
# 2、内存中的数据是可以修改的
2.2 覆盖写
优点:硬盘只占用一块空间
缺点:数据量较大的时候会造成内存溢出
# 方式1:覆盖写
with open(r'demo.txt', 'r', encoding='utf8') as f:
data = f.read()
print(data)
new_data = data.replace('NB', 'DB')
with open(r'demo.txt', 'w', encoding='utf8') as f1:
f1.write(new_data)
print(new_data)
2.3 重命名
优点:不会造成内存溢出
缺点:有那么一段时间需要占用硬盘两个地方的空间(可能) 也可能是在内存中创建没有刷到硬盘
import os
with open('demo.txt', 'r', encoding='utf8') as read_f, \
open('.demo.txt.swap', 'w', encoding='utf8') as wrife_f:
for line in read_f:
wrife_f.write(line.replace('DB', 'SDB'))
os.remove('demo.txt') # 删除文件
os.rename('.demo.txt.swap', 'demo.txt') # 重命名文件
3.函数简介
我们自己瞎写的缺陷
1.只能统计某个固定的数据类型里面的数据值个数
2.没有产生新的值(返回值)
l1 = [1, 2, 3, 4, 5, 6]
# print(len(l1)) # 不允许使用len 完成列表数据值个数统计
# 自定义统计方法
def my_len():
value_count = 0
for i in l1:
value_count += 1
print(value_count)
1.循环
在相同的位置反复执行相同的代码
2.函数
在不同的位置反复执行相同的代码