文件内光标的移动
# 1.在文本模式下read括号内的数字表示读取几个字符
# with open(r'aaa.txt', 'r',encoding='utf8') as f:
# data = f.read(3) # 文件内光标的移动
# print(data) # 文件内
# 2.在二进制模式下read括号内的数字表示读取几个字节(英文一个字节,中文三个字节)
# with open(r'aaa.txt','rb') as f:
# data = f.read(6)
# print(f.tell()) # 6 tell() 获取光标移动的字节数
# print(data.decode('utf8')) # 文件
"""
3. seek(offset,whence)
offset 控制光标的位移量(字节)
whence 模式
0 基于文件开头移动多少字节
1 基于光标当前所在位置移动多少字节
2 基于文件末尾移动多少字节
ps:1和2只能在二进制模式下使用 0无所谓
"""
# with open(r'aaa.txt','r',encoding='utf8') as f:
# data = f.read(3)
# print(data) # 文件内
# print(f.tell()) # 9
# data1 = f.read()
# print(data1) # 光标的移动
# 代码控制光标移动
# with open(r'aaa.txt','r',encoding='utf8') as f:
# data = f.read()
# print(data) # 文件内光标的移动
# f.seek(0,0) # 将文件光标移动到文件开头
# print(f.read()) # 文件内光标的移动
# with open(r'aaa.txt','rb') as f:
# data = f.read(6)
# print(data) # b'\xe6\x96\x87\xe4\xbb\xb6'
# print(data.decode('utf8')) # 文件
# f.seek(-3,1) # 将光标在当前位置往后移动3个字节
# print(f.read().decode('utf8')) # 件内光标的移动
# f.seek(-3,2) # 将光标移动到文件末尾的倒数第三个字节
# print(f.read().decode('utf8')) # 动
# 小练习:实现动态查看最新一条日志的效果
import time
with open('xxx.txt','rb') as f:
f.seek(0,2) # 每次读取完都将光标移动到文件末尾
while True:
line = f.readline()
if len(line) == 0:
# 没有内容
time.sleep(1)
else:
print(line.decode('utf-8'),end='')
文件内数据修改
"""
机械硬盘存储数据的原理
1.数据的修改 其实是覆盖写
2.数据的删除 占有态自由态
"""
代码修改文件的方式
1.覆盖写
先读取文件内容到内存,在内存中完成修改,之后w模式打开该文件写入
2.重命名
先读取文件内容到内存,在内存中完成修改,之后保存到另外一个文件中,再将原文件删除,将新的文件重命名为原文件
# 方式1:覆盖写
with open(r'xxx.txt','r',encoding='utf8') as f:
data = f.read()
new_data = data.replace('你好','hello')
with open(r'xxx.txt','w',encoding='utf8') as f1:
f1.write(new_data)
"""
优点:硬盘只占用一块空间
缺点:数据量较大的时候会造成内存溢出
"""
# 方式2:重命名
import os
with open('demo.txt','r',encoding='utf8') as read_f,open('.demo.txt.swap','w',encoding='utf8') as write_f:
for line in read_f:
write_f.write(line.replace('你好','nihao'))
os.remove('demo.txt') # 删除文件
os.rename('.demo.txt.swap','demo.txt') # 重命名
"""
优点:不会造成内存溢出
缺点:有那么一段时间需要占用硬盘的两个地方的空间 也可能是在内存中创建没有刷到硬盘
"""
函数简介
l1 = [1,2,3,4,5,6]
# print(len(l1)) # 不允许使用len 完成列表数据值个数统计
# 自定义统计方法
def my_len(x):
value_count = 0
for i in l1:
value_count +=1
print(value_count)
"""
这个函数
1.只能统计某个固定数据类型里面的数据值个数
2.没有产生新的值(返回值)
"""
"""
1.循环:在相同的位置反复执行相同的代码
2.函数:在不同的位置反复执行相同的代码
"""
print(len(l1))
my_len(l1)
案例
1.尝试着将昨天第二题注册、登录功能封装成函数
x = ''
t = ''
name_list = []
def register():
name_register = input('请输入用户姓名>>>:').strip()
with open('userinfo.txt', 'r', encoding='utf8') as file_r:
for line in file_r:
real_name = line.split('|')[0]
if name_register == real_name:
print('该用户已注册')
break
else:
pwd_register = input('请输入用户密码>>>:').strip()
name_pwd_register = '%s|%s\n' % (name_register, pwd_register)
with open('./userinfo.txt', 'a', encoding='utf8') as file:
file.write(name_pwd_register) # 将账户密码写入文件
file.flush()
print('用户注册成功')
def login():
name_login = input('请输入用户姓名>>>:').strip()
pwd_login = input('请输入用户密码>>>:').strip()
name_pwd_login = '%s|%s' % (name_login, pwd_login)
with open('userinfo.txt', 'r', encoding='utf8') as file1:
l_list = [ line.strip() for line in f ]
file1.flush()
if name_pwd_login in name_list:
print('登录成功')
global x
x = name_login # 将登录成功的用户名和密码修改为全局名称空间的值
global t
t = pwd_login
else:
print('用户名或者密码错误')
def func_exit():
print(f'用户{x}正在退出...')
def outer(func):
def wrapper(*args, **kwargs):
try:
if '%s|%s' % (x, t) in name_list:
func(*args, **kwargs)
else:
print('未登录没有权限您的修改密码')
except NameError:
print('请先正确登录')
return wrapper
@outer
def chick_info():
modify= input(f'您当前的用户名为>>>:{x},密码为>>>:{t},确认y,其他退出')
if modify == 'y':
new_pwd = input('请输入新的密码>>>:')
with open('userinfo.txt', 'r', encoding='utf8') as f:
l_list = []
for line in f:
l_list.append(line.strip())
with open('userinfo.txt', 'r', encoding='utf8') as f2:
res = f2.read()
with open('userinfo.txt', 'w', encoding='utf8') as f1:
if f'{x}|{t}' in l_list:
print(x, t)
f1.write(res.replace(t, new_pwd))
f1.flush()
print('密码修改成功')
else:
return
while True:
print("""
1.用户注册功能
2.用户登录功能
3.修改用户密码
4.退出用户登录
""")
func_id = input('请输入功能编号')
if func_id == '3':
chick_info()
if func_id == '1':
register()
if func_id == '2':
login()
if func_id == '4':
func_exit()
break