python学习笔记

今日内容概要

  • 作业讲解
  • 文件内光标的移动
  • 文件数据修改
  • 函数简介

今日内容详细

作业讲解

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

# 1.先获取想要拷贝的数据路径
source_file_path = input('请输入想要拷贝的数据路径:').strip()
# 2.再获取拷贝到哪个地方的目标路径
target_file_path = input('请输入拷贝到哪个地方的目标路径:').strip()
# 3.读取想要拷贝的数据路径对应的内容,并写入到目标路径中
with open(r'%s' % source_file_path, 'rb') as f1, open(r'%s' % target_file_path, 'wb') as f2:   # 合并代码并让路径添加r取消转移
    for line in f1:   # 循环读取文件中一行行内容
        f2.write(line)   # 依次写入新的文件

2.利用文件充当数据库编写用户登录、注册功能
文件名称:userinfo.txt
基础要求:
用户注册功能>>>:文件内添加用户数据(用户名、密码等)
用户登录功能>>>:读取文件内用户数据做校验
ps:上述功能只需要实现一次就算过关(单用户) 文件内始终就一个用户信息
拔高要求:
用户可以连续注册
用户可以多账号切换登录(多用户) 文件内有多个用户信息
ps:思考多用户数据情况下如何组织文件内数据结构较为简单
提示:本质其实就是昨天作业的第二道题 只不过数据库由数据类型变成文件

while True:
    print("""
    1.注册功能
    2.登录功能
    3.退出程序
    """)
    func_id = input('请输入功能编号:').strip()
    if func_id == '1':
        # 1.获取用户名
        username = input('请输入用户名:').strip()
        # 2.判断当前用户名是否已存在
        # 2.1读取数据文件
        with open(r'userinfo.txt', 'r', encoding='utf8') as f:
            # 2.2循环获取文件内容(一个个用户数据)
            for line in f:   # jason|123  kevin|321  tony|222
                # 2.3拆分真实用户名比对
                real_name = line.split('|')[0]
                # 2.4判断用户名是否存在
                if username == real_name:
                    print('用户名已存在')
                    break
            else:
                password = input('请输入密码:')
                # 3.构造用户数据
                user_data = '%s|%s\n' %(username, password)
                # 4.打开并写入文件
                with open(r'userinfo.txt', 'a', encoding='utf8') as f:
                    f.write(user_data)
                print(f'用户{username}注册成功')
    elif func_id == '2':
        # 1.获取用户数据
        username = input('username:').strip()
        password = input('password:').strip()
        # 2.读取文件内容
        with open(r'userinfo.txt', 'r', encoding='utf8') as f:
            # 2.1循环读取每个真实用户的数据
            for line in f:   # oscar|666  jerry|789
                # 2.2拆分真实用户名和密码
                real_name, real_pwd = line.split('|')   # 注意密码后面有换行符
                # 2.3判断用户输入的数据与真实数据是否一致
                if username == real_name and password == real_pwd.strip('\n'):
                    print('登录成功')
                    break
                else:
                    print('用户名或密码错误')
    elif func_id == '3':
        print('欢迎下次再来')
        break
    else:
        print('请按指令输入')

文件读写模式补充

描述
r 只读取 ,文件不存在时则报错,文件存在文件内指针直接跳到文件开头
w 只写入,文件不存在时会创建空文档,文件存在会清空文件,文件指针跑到文件开头
x 只写入,文件已存在则无法创建文件和写入内容
a 只追加写,文件不存在时会创建空文档,文件存在会将文件指针直接移动到文件末尾
t 文本模式(默认值,与其他模式结合使用)
b 二进制模式(与其他模式结合使用)
+ 读写模式(与其他模式结合使用)
rb 以二进制格式打开一个文件用于只读
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
ab 以二进制格式打开一个文件用于追加,如果该文件已存在,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
r+ 打开一个文件用于读写
rb+ 以二进制格式打开一个文件用于读写
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
a+ 打开一个文件用于读写,如果该文件已存在,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
ab+ 以二进制格式打开一个文件用于追加,如果该文件已存在,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
f = open('a.txt', 'r+', encoding='utf8')  # 读取⽂件的时候使⽤utf8编码
content = f.read()
print(content)
f.write('123')  # 使⽤r+模式可以直接读和写,先读后写的话:写⼊的时候从⽂本最后⾯开始,直接追加
# 如果是先写后读,则从⽂本开头写⼊,会覆盖对应个数的字符
f.close()

文件内光标的移动

在文本模式下read括号内的数字表示读取几个字符

with open(r'a.txt', 'r', encoding='utf8') as f:
data = f.read(3)  # 读取3个字符

在二进制模式下read括号内的数字表示读取几个字节(英文一个字节 , 中文三个字节)

with open(r'a.txt', 'rb') as f:
data = f.reaad(3)  # 读取3个字节

之前文件内指针的移动都是由读/写操作而被动触发的,若想读取文件某一特定位置的数据,则则需要用f.seek方法主动控制文件内指针的移动,详细用法如下:
seek(offset,whence)
offset:控制光标移动的字节数
whence:模式
0:默认模式,代表指针移动的的字节数是以文件开头为参照的
1:代表指针移动的字节数是以当前所在位置为参照的
2:代表指针移动的字节数是以文件末尾的位置为参照的
ps:1和2只能在二进制模式下使用,0无所谓

0模式的使用

# a.txt用utf8编码,内容:abc你好
with open(r'a.txt', 'r', encoding='utf8') as f:
    f.seek(3,0)   # 参照文件开头移动了3个字节
    print(f.tell())  # 查看当前文件指针距离文件开头的位置,输出结果:3
    print(f.read())  # 从第三个字节的位置读到文件末尾,输出结果:你好
    # 注意:由于在t模式下,会将读取的内容自动解码,所以必须保证读取内容是一个完整中文数据,否则解码失败
with open(r'a.txt', 'rb') as f:
    f.seek(6,0)
    print(f.read().decode('utf8'))  # 输出结果:好

1模式的使用

with open(r'a.txt', 'rb') as f:
    f.seek(3,1)  # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头
    print(f.tell()) # 输出结果:3
    f.seek(4,1)  # 从当前位置往后移动4个字节,而此时的当前位置为3
    print(f.tell())  # 输出结果:7

2模式的使用

# a.txt用utf8编码,内容:abc你好
with open(r'a.txt', 'rb') as f:
    f.seek(0,2)  # 参照文件末尾移动0个字节,即直接跳到文件末尾
    print(f.tell()) # 输出结果:9
    f.seek(-3,2)  # 参照文件末尾往前移动了3个字节
    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('utf8'), end='')

文件内数据修改

代码修改文件的方式:
1.覆盖写
先读取文件内容到内存,在内存中完成修改之后w模式打开该文件写入
2.重命名
先读取文件内容到内存,在内存中完成修改之后保存到另外一个文件中
再将原文件删除,将新的文件重命名为原文件

"""
机械硬盘存储数据的原理
1.数据的修改,其实是覆盖写
2.数据的删除,是由占有态变为自由态
"""

方式1:覆盖写
with open(r'demo.txt', 'r', encoding='utf8') as f:
data = f.read()
new_data = data.replace('dsb', 'nb')
with open(r'demo.txt', 'w', encoding='utf8') as f1:
f1.write(new_data)

"""
优点:硬盘只占用一块空间
缺点:数据量较大的时候会造成内存溢出
"""


方式2:重命名
import os

with open(r'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('nb', 'sb'))
os.remove('demo.txt')  # 删除文件
os.remove('.demo.txt.swap', 'demo.txt')  # 重命名文件

"""
优点:不会造成内存溢出
缺点:有那么一段时间需要占用硬盘两个地方的空间(可能),也可能实在内存中创建没有刷到硬盘
"""

函数简介

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.没有产生新的值(返回值)
"""

"""
1.循环
    在相同的位置反复执行相同的代码
2.函数
    在不同的位置反复执行相同的代码
"""

print(len(l1))
print(my_len())

作业

with open(r'userinfo.txt', 'a', encoding='utf8') as f:
    pass


def registered_user(username, password):
    """
    注册用户
    :return:
    """
    user_data = '%s|%s\n' % (username, password)
    with open(r'userinfo.txt', 'a', encoding='utf8') as f:
        f.write(user_data)
        print(f'用户{username}注册成功')
def auth_user(username, password):
    """
    用户身份验证
    :return:
    """
    with open(r'userinfo.txt', 'r', encoding='utf8') as f:
        for line in f:
            real_name, real_pwd = line.split('|')
            if username == real_name and password == real_pwd.strip('\n'):
                return True
            else:
                return False
while True:
    print("""
    1.注册功能
    2.登录功能
    """)
    func_id = input('请输入功能编号:').strip()
    if func_id == '1':
        username = input('请输入用户名:').strip()
        password = input('请输入密码:').strip()
        registered_user(username, password)
    elif func_id == '2':
        username = input('username:').strip()
        password = input('password:').strip()
        i = auth_user(username, password)
        if i:
            print('登录成功')
        else:
            print('登录失败')
    else:
        print('请按指令输入')
posted @   空白o  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示