登录注册功能的优化、文件内光标的移动、文件数据的修改、函数简介、其他文件操作的读写模式

补充知识

1.r+'文件路径'的作用:为了取消撬棍与字母组合的特殊含义
2.用户输入字符串后,常常会去一个变量名给予赋值操作,当对该变量名进行操作的时候,如果想要对该字符串增加字符或取消转义,常常会使用占位符(%s)、格式化输出(.format)
3.循环数据类型的时候尽量不要修改数据类型内部的数据值个数
  eg:
    l1 = [1,2,3,4,5,6,7,8]
    for i in l1:
        l1.pop()
        print(i)  # i 取值1,2,3,4
    print(l1)  # [1, 2, 3, 4]
  ps:不允许出现这种情况

作业优化

1.编写简易版本的拷贝工具
自己输入想要拷贝的数据路径 自己输入拷贝到哪个地方的目标路径
任何类型数据皆可拷贝
ps:个别电脑C盘文件由于权限问题可能无法拷贝 换其他盘尝试即可

resource_path = input("请输入你想要拷贝文件的路径>>>:").strip()
target_path = input("请输入你拷贝的文件的目标路径>>>:").strip()
with open(r'%s' % resource_path, 'rb')as f1, open(r'%s'%target_path,'wb')as f2:
    for line in f1:
        f2.write(line)

2.利用文件充当数据库编写用户登录、注册功能
文件名称:userinfo.txt
1.基础要求:
用户注册功能>>>:文件内添加用户数据(用户名、密码等)
用户登录功能>>>:读取文件内用户数据做校验
ps:上述功能只需要实现一次就算过关(单用户) 文件内始终就一个用户信息

1.单个用户注册功能
real_name = input("请输入你想要注册的用户名>>>:").strip()
with open(r'userinfo.txt','r',encoding='utf8') as f1:
    data = f1.read()
    data1=data.split('|')[0]
    if data1 ==real_name:
        print("用户名已经存在")
    else:
        real_pwd = input("请输入你注册的用户名密码>>>:").strip()
        with open(r'userinfo.txt','w',encoding='utf8') as f2:
            f2.write(f'{real_name}|{real_pwd}')
            print("注册成功")
            
2.单个用户登录功能
in_name = input("请输入你的用户名>>>:").strip()
in_pwd = input("请输入你的密码>>>:").strip()
with open(r'userinfo.txt','r',encoding='utf8') as f1:
    info_name,info_pwd = f1.read().split('|')
    if info_name == in_name and info_pwd ==in_pwd:
            print("登录成功")
    else:
        print("登录失败")

​ 2拔高要求:
​ 用户可以连续注册
用户可以多账号切换登录(多用户) 文件内有多个用户信息
​ ps:思考多用户数据情况下如何组织文件内数据结构较为简单
提示:本质其实就是昨天作业的第二道题 只不过数据库由数据类型变成文件

while True:
    print("""
    1.注册功能
    2.登录功能
    3.退出
    """)
    choice = input("请输入你的指令>>.:").strip()
    if choice == '1':
        add_name = input("请输入你想要注册的用户名>>>:").strip()
        with open(r'userinfo.txt','r',encoding='utf8') as f1:
            for line in f1:
                real_name = line.split('|')[0]
                if real_name == add_name:
                    print("用户名已存在")
                    break
            else:
                add_pwd =input("请输入你的密码>>>:").strip()
                with open(r'userinfo.txt','a',encoding='utf8') as f2:
                    f2.write(f'{add_name}|{add_pwd}\n')
                    print(f'用户名{add_name}注册成功')

    elif choice == '2':
        in_name = input("请输入你的用户名>>>:").strip()
        in_pwd = input("请输入你的密码>>>:").strip()
        with open(r'userinfo.txt','r',encoding='utf8') as f1:
            for line in f1:
                info_name,info_pwd = line.strip().split('|')
                if info_name == in_name and info_pwd == in_pwd:
                    print("登录成功")
                    break
            else:
                print("登录失败")

    elif choice == '3':
        print("欢迎下次再来")
        break
    else:
        print("请输入正确的指令")

​ 3.注册、登录功能封装成函数

def login():
    in_name = input("请输入你的用户名>>>:").strip()
    in_pwd = input("请输入你的密码>>>:").strip()
    with open(r'userinfo.txt', 'r', encoding='utf8') as f1:
        for line in f1:
            info_name, info_pwd = line.strip().split('|')
            if info_name == in_name and info_pwd == in_pwd:
                print("登录成功")
                break
        else:
            print("用户名或密码错误")



def register():
    add_name = input("请输入你想要注册的用户名>>>:").strip()
    with open(r'userinfo.txt', 'r', encoding='utf8') as f1:
        for line in f1:
            real_name = line.split('|')[0]
            if real_name == add_name:
                print("用户名已存在")
                break
        else:
            add_pwd = input("请输入你的密码>>>:").strip()
            with open(r'userinfo.txt', 'a', encoding='utf8') as f2:
                f2.write(f'{add_name}|{add_pwd}\n')
                print(f'用户名{add_name}注册成功')

while True:
    print("""
    +++++++++++++功能++++++++++++++++++++++++++
    1.注册功能
    2.登录功能
    +++++++++++++++++++++++++++++++++++++++
    """)
    choice = input("请输入你的指令>>.:").strip()
    if choice == '1':
        register()
    elif choice =='2':
        login()
    else:
        print("请输入正确的指令")

文件内光标的移动

控制文件光标的移动主要有read()、seek()方法

read()方法控制文件光标的移动

read()方法在两种操作模式(t模式、b模式)用法有所不同

1.t模式(文本模式):read(n)表示读取几个字符
  ps:a.txt的文件内容是:hah你在干嘛ne
  eg:
  with open(r'a.txt','r',encoding='utf8') as f1:     
      print(f1.read(3))  # hah
      print(f1.read(3))  # 你在干
2.b模式(二进制模式):read(n)表示读取几个字节(英文1个字节,中文3个字节起步)
  ps:a.txt的文件内容是:hah你在干嘛ne
  eg:
  with open(r'a.txt','rb') as f1:
      data = f1.read(9)
      print(data.decode('utf8'))  # hah你在
      print(f1.read(6).decode())  # 干嘛
ps:tell()可以获取光标的字节数(从文件内容的开头到光标距离的字节数)
  eg:
  with open(r'a.txt','r',encoding='utf8') as f1:
      print(f1.read(6))  # hah你在干
      print(f1.tell())  # 12

seek(offset,whence)方法控制文件光标的移动

1.offset指光标移动的位移量
2.whence 模式(有0、1、2模式)>>> 1和2模式只能在二进制模式下使用 0模式在t、b模式下都可以
  seek(n,0/1/2)  >>>当n为负数时,光标向左移动n个字节;当n为正数时,光标向右移动n个字节
  2.1 -- 0模式	>>>基于文件开头往后移动n个字节的位移量(offset),然后开始读取后面的字符
		eg:
         with open(r'a.txt','r',encoding='utf8') as f1:
             f1.seek(6,0)
             print(f1.seek(6,0))  # 6 
             print(f1.read())  # 在干嘛ne
         with open(r'a.txt','rb') as f1:
             f1.seek(6,0)
             print(f1.seek(6,0))  # 6
             print(f1.read().decode())  # 在干嘛ne
  2.2 -- 1模式	>>>基于光标当前位置移动n个字节的位移量(offset),然后开始读取后面字符
		eg:
         with open(r'a.txt','rb') as f1:
             print(f1.read(6).decode('utf8'))  # hah你
             f1.seek(3,1)  
             print(f1.read().decode())  # 干嘛ne
         with open(r'a.txt','rb') as f1:
             print(f1.read(6).decode('utf8'))   # hah你
             f1.seek(-3,1)  
             print(f1.read().decode())  # 你在干嘛ne
  2.3 -- 2模式	>>>基于文件末尾移动n个字节的位移量(offset),然后开始读取后面的字符
		eg:
         with open(r'a.txt','rb') as f1:
             f1.seek(-8,2)
             print(f1.read().decode())  # 你在干嘛ne
  ps:a.txt的文件内容是:hah你在干嘛ne

文件内数据的修改

​ 首先要了解机械硬盘存储数据的原理:数据的修改,其实就是覆盖写;数据的删除,涉及到占有态和自由态,当数据被删除时,该占有的内存地址被恢复成自由态。处于自由态时,其实可以通过数据恢复来找回原有被删除的数据,这提醒我们谨慎卖电子产品。为了以防信息泄露,最可靠的办法是:先删除原有数据(恢复自由态),再下载一个占满内存空间的无关信息,最后再删除这个无关信息(当不法分子恢复数据时,只能恢复我们后面下载的无关信息)

覆盖写

1.实质:先读取文件内容到内存,然后在内存中进行修改(运用字符串的内置方法),最后用w模式打开文件进行写入
2.优缺点
	优点:硬盘只占用一块空间
     缺点:数据量较大时,会造成内存溢出
3.实操
	with open(r'a.txt','r',encoding='utf8') as f1:
        data = f1.read()
        data1 = data.replace('nice','bad')
	with open(r'a.txt','w',encoding='utf8') as f2:
    	f2.write(data1)

重命名

1.实质:先读取文件内容到内存,然后在内存中进行修改,之后保存到另一个文件中,再将原文件删除,最后将新的文件重命名为原文件的名字(会导入os模块)
2.优缺点
	优点:不会造成内存溢出
    缺点:有那么一段时间可能需要占用硬盘两个地方的空间,也可能时在内存中创建没有,并没有刷到硬盘
3.实操
    import os
    with open(r'a.txt','r',encoding='utf8') as f1,open(r'b.txt','w',encoding='utf8') as f2:
        for line in f1:
            f2.write(line.replace('bad','nice'))
    os.remove('a.txt')  # 删除原文件
    os.rename('b.txt','a.txt')  # 重命名

函数简介

1.定义函数:函数必须遵循先定义后调用的规则。
	语法结构:
	def 函数名(参数1,参数2...):
		函数体
        return 返回值
2.函数与循环的区别
	函数:在不同位置反复执行的相同代码
    循环:在相同位置反复执行的相同代码

文件操作的其他读写模式

前面我们了解到了r模式、w模式、a模式、rb模式、wb模式、ab模式,其实还有r+模式、w+模式、a+模式、rb+模式、wb+模式、ab+模式

在文件读写模式中"+"的含义:open a disk file for updating (reading and writing)>>>表示既可以读又可以写
1.r+模式:读写模式
  1.1 新写的内容会覆盖原文件的内容,但他不会全部覆盖完,写入几个字符就覆盖几个字符,从文件开头开始写入
  1.2  写入内容后,光标会停留在写入的文件内容后面,之后读取的内容就是没有没覆盖的原内容
  with  open(r'a.txt','r+',encoding='utf-8') as f1:
      f1.write('0000')  # 0000覆盖前面4个的字符
      print(f1.read())  # 读取的时0000之后的内容
2.w+模式:写读模式  >>>因为‘W’会先把文件里面的内容清空掉,再去读,读到的内容就是空
  with open(r'a.txt', 'w+', encoding='utf-8') as f1:
      f1.write('呜呜')  # 重新写入
      f1.read()  # 读取的内容为空 光标在最后
3.a+模式:文件内容没有被清空,并在内容末尾追加新增的内容;文件指针默认在末尾,读取的内容为空
  with open(r'a.txt', 'a+', encoding='utf-8') as f1:
     f1.write('呜呜')  # 追加写入
     f1.read()  # 空的
4.rb+模式:以二进制格式打开一个文件用于读写,文件指针将会放在文件的开头,一般用于非文本文件如图片等
5.wb+模式:以二进制格式打开一个文件用于读写,如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除;如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
6.ab+模式:二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写

posted @ 2022-06-30 20:04  DRAMA-娜娜  阅读(36)  评论(0编辑  收藏  举报