文件补充和函数简介
文件补充
文件内光标的移动
引入
with open(r'txt1.txt', 'r', encoding='utf8') as f:
print(f.read(12)) # read在文本模式下,括号内的数字表示读取指定的字符个数
print(f.read(1))
print(f.read(5))
with open(r'txt1.txt', 'rb') as f:
print(f.read(36).decode('utf8')) # read在二进制模式下,括号内的数字表示读取指定的bytes数
print(f.read(3).decode('utf8'))
print(f.read(24).decode('utf8'))
print(f.read(11).decode('utf8'))
print(f.read(1).decode('utf8'))
'''
unicode所有的字符都是2bytes起步来表示,包括英文
utf8中文,中文标点符号用3bytes来表示,英文,英文标点符号用1bytes来表示
'''
控制光标的移动
seek关键字可以控制光标的移动,在文本模式和二进制模式中移动的单位均是字节数
语法结构:
seek(offset,whence)
offset:控制移动的字节数
whence:控制模式
0:让光标先移动到文件开头,支持文本模式和二进制模式
1:让光标先停留在当前位置,只支持二进制模式,文本模式下使用可能报错(offset为0时不报错)
2:让光标先移动到文件末尾,只支持二进制模式,文本模式下使用可能报错(offset为0时不报错)
with open(r'txt1.txt', 'r', encoding='utf8') as f:
print(f.read()) # 读取全部内容
print(f.seek(36, 0)) # 中文字符按照一个字符三个字节移动
print(f.read()) # 读取光标以后的内容
with open(r'txt1.txt', 'rb') as f:
print(f.read(36).decode('utf8'))
f.seek(3, 1) # 基于当前位置,往后移动三个字节
f.seek(-5, 2) # 基于文件末尾,往前移动三个字节
print(f.tell()) # 获取光标基于文件开头的字节数
print(f.read().decode('utf8'))
实时检测文件
检测文件内是否有新增的内容,有的话打印新增的内容(很少用)
with open('aaa.log', 'rb') as f:
f.seek(0, 2)
f1 = f
while True:
str1 = f1.readline()
if len(str1) == 0:
pass
else:
print(str1.decode('utf-8'), end='')
文件的修改
硬盘上的数据的两个状态
占有态与自由态
数据删除和存储的本质:
删除数据其实就是将数据原来的位置标记成自由态,之后存储新的数据遇见自由态的数据会直接覆盖
# 方式一:将文件内容一次性全部读入内存,然后在内存中修改完后先清除原文件再写入
# 优点: 在文件修改过程中同一份数据只有一份
# 缺点: 会过多地占用内存
with open('txt2.txt', 'r', encoding='utf-8') as f:
data = f.read()
with open('txt2.txt', 'w', encoding='utf-8') as f:
f.write(data.replace('一辈子', '终身'))
with open('txt2.txt', 'r', encoding='utf-8') as f:
data = f.read()
print(data)
# 方式二:以读的方式打开原文件,同时以写的方式打开另一个临时文件;for循环一行行读取原文件内容,修改完后写入临时文件,删掉原文件,将临时文件重命名原文件名
# 优点: 不会占用过多的内存
# 缺点: 在文件修改过程中同一份数据有两份
import os # 模块
with open('txt2.txt', 'r', encoding='utf-8') as read_file, open('.txt2.txt.swap', 'w', encoding='utf-8') as write_file:
for line in read_file: # for循环一行行读取原文件内容
write_file.write(line.replace('一辈子', '终身')) # 修改文件
os.remove('txt2.txt') # 删除原文件
os.rename('.txt2.txt.swap', 'txt2.txt') # 重命名文件
with open('txt2.txt', 'r', encoding='utf-8') as read_file: # 以读的方式打开修改后的文件
f2 = read_file.readlines()
print(f2)
函数
函数简介
# 统计字符串长度
str1 = '只有在那崎岖的小路上不畏艰险奋勇攀登的人,才有希望达到光辉的顶点'
def my_len():
count = 0
for i in str1:
count += 1
print('字符串中字符的个数', count)
print(len(str1)) # 32
my_len() # 字符串中字符的个数 32
# 使用函数写注册登录
def func_1():
''''功能是提供输入用户名和密码界面'''
username = input('请输入您的用户名>>>:').strip() # 密码输入界面
password = input('请输入密码>>>:').strip() # 密码输入界面
return (username, password) # 返回值是一个元组,里面有两个元素,分别是用户名和密码
def rt_func():
'''功能是只读模式打开文本文件,返回值为一个列表,里面的元素是文本的一行行内容'''
with open(r'userinfo2.txt', 'r', encoding='utf8') as f:
f2 = f.readlines()
return f2
def at_func(a):
'''功能是只追加模式打开文本文件,把参数一写入文本文件'''
with open(r'userinfo2.txt', 'a', encoding='utf8') as f1:
f1.write(a)
flag = True
with open(r'userinfo2.txt', 'a', encoding='utf8'): # 创建一个文本用来存储用户信息
pass # 补全语法
while flag:
print('''------------------欢迎使用-----------------------------
\n1.注册功能\n2.登陆功能\n3.退出功能
''')
choice = input('请输入功能编号>>>:').strip() # 功能选择界面
if choice == '1':
username, password = func_1() # 调用函数,解压赋值
print('用户注册界面'.center(20, '-'))
for line in rt_func(): # for循环一行行取文本内容
if username == line.split('^')[0]: # 判断用户名是否存在
print('用户名已存在')
break
else:
data = f'{username}^{password}\n' # 拼接用户信息
at_func(data) # 调用函数把data写入文本
print(f'{username}注册成功,请记住您的密码{password}')
elif choice == '2':
print('用户登陆界面'.center(20, '-'))
count = 1
while count < 4:
username, password = func_1() # 调用函数,解压赋值
count += 1
for line in rt_func(): # 调用函数返回一个列表用于for循环
if username == line.split('^')[0]: # 判断用户名是否存在
if password == line.split('^')[1].strip(): # 判断密码是否正确
print(f'{username}登陆成功')
count = 4
break
else:
print('用户名或密码错误')
elif choice == '3':
flag = False
else:
print('请重新输入')