python第十课--文件内光标移动实战,文件数据修改底层代码,函数的相关知识
昨日内容回顾
-
文件基本操作
方式1 f1 = open(文件路径,操作模式,encoding='utf8') f1.方法 f1.close() 方式2 with open(文件路径,操作模式,encoding='utf8') as f2: f2.方法 # 子代码运行结束自动调用f2.close() ps:文件路径的字符串前面加了r,取消\与字母可能产生的特殊含义
-
文件读写模式
r 只读模式 文件路径不存在直接报错 存在则打开文件等待读取 w 只写模式 文件路径不存在自动创建 存在则先清空文件内容然后等待写入 a 只追加模式 文件路径不存在自动创建 存在则自动在文件末尾等待写入
-
文件操作模式
t 文本模式 默认的操作模式 rt wt at 1.只能操作文本文件 2.读写都是以字符为单位 3.需要指定encoding参数一般就是'utf8' b 二进制模式 1.能够操作所有类型的文件 2.读写都是以bytes为单位 3.不需要指定encoding参数
-
文件诸多方法
1.read() 括号内不写数字则一次性读取文件内容 当文件内容较大的时候可能会造成内存溢出 括号内可以写数字 在不同模式下意思是读取几个字符或者几个字节 2.for循环 文件对象支持for循环一行行读取文件内容 3.readable() 判断文件是否可读 4.readline() 读取一行文件内容 5.readlines() 一次性读取文件内容 按照行数组织成列表中一个个数据值 6.wirte() 写入数据 7.writeable() 判断文件是否可写 8.writelines() 传列表 会自动将列表中所有的数据值写入 9.flush() 相当于ctrl + s
-
文件内光标的移动
seek(偏移量,模式) 偏移量只能以字节为单位,不管在文本模式或者bytes模式下 模式有三种0 1 2 0基于文件开头文本与二进制模式都可以使用 1只有二进制模式可以使用,在文本模式打开seek括号里面模式写1,程序会直接报错 2只有二进制模式可以使用,在文本模式打开seek括号里面模式写2,程序会直接报错 tell() 获得当前光标距离文件开头产生的字节数
今日内容概要
- 作业讲解
- 文件内光标的移动实战演练
- 计算机硬盘存取数据的原理
- 文件内容修改
- 函数简介
- 函数的语法结构
- 函数的定义与调用
今日内容详细
作业讲解
source 来源(n) 获得;找出……的来源(V)
target目标;靶子(n) 把……作为目标(v)
1.编写简易版本的拷贝工具
自己输入想要拷贝的数据路径 自己输入拷贝到哪个地方的目标路径
任何类型数据皆可拷贝
ps:个别电脑C盘文件由于权限问题可能无法拷贝 换其他盘尝试即可
代码实现:
source_file_path = input('请输入您想要拷贝的文件路径>>>:').strip() # 1.获取想要拷贝的文件路径,路径要详细到你复制的文件的文件名。
target_file_path = input('请输入您想要拷贝到哪个地方的路径>>>:').strip() # 2.获取目标文件的路径,注意这个地方的目标文件路径包括你要生成的这个文件的文件名
with open(r'%s' % source_file_path, 'rb') as read_f, open(r'%s' % target_file_path, 'wb') as write_f:
for line in read_f:
write_f.write(line)
# 3.第三行代码的主要功能是: 打开第一个文件路径 读取内容写入第二个文件路径中,主要就是将想要拷贝的文件路径与要拷贝到的路径对应的变量名,利用格式化输出输出为路径的字符串模式,这个地方也可以直接写变量名像这样with open(source_file_path, 'rb') as read_f 但是这种方式有可能因为路径种的 \与一些字母的组合会产生特殊的含义 导致路径查找混乱。所以利用格式化输出是最稳的方式。
# 4.注意格式化输出时 %s一定要在''里面
- 利用文件充当数据库编写用户登录、注册功能 要理解重要!!!!!
文件名称:userinfo.txt
基础要求:
用户注册功能>>>:文件内添加用户数据(用户名、密码等)
用户登录功能>>>:读取文件内用户数据做校验
ps:上述功能只需要实现一次就算过关(单用户) 文件内始终就一个用户信息
拔高要求:
用户可以连续注册
用户可以多账号切换登录(多用户) 文件内有多个用户信息
ps:思考多用户数据情况下如何组织文件内数据结构较为简单
提示:本质其实就是昨天作业的第二道题 只不过数据库由数据类型变成文件
while True:
print("""
1.注册功能
2.登录功能
""")
choice = input('请选择您想要执行的功能编号>>>:').strip()
if choice == '1':
username = input('please input your username>>>:').strip() # 1.获取用户名和密码
password = input('please input your password>>>:').strip()
with open(r'userinfo.txt', 'r', encoding='utf8') as f: # 2.必须先在当前的项目文件夹下先新建这个文件名,才能打开这个文件
for line in f: # 3.for循环遍历出文件夹里面的每一行内容,如果文件夹里面第一行有数据就读出来了'jason|123'
real_name, real_pwd = line.split('|') # 4.读出的字符串切割成列表解压赋值给两个变量名
if username == real_name: # 5.校验用户名是否等于刚刚解压赋值的变量名,确定用户名是否已存在,如果不存在继续for循环,再比对
print('用户名已存在 无法完成注册')
break # 6.一旦确定用户名已存在,就没有必要继续往下校验是否重复了,直接结束循环,
else:
# 7.当for循环体子代码没有被break结束的情况下,for遍历完了,才执行else子代码,也就是遍历完了,全部判断完了,确认用户名不在文件夹里面
with open(r'userinfo.txt', 'a', encoding='utf8') as f1: # 8.执行追加模式打开文件
f1.write(f'{username}|{password}\n') # 9.对该文件执行写入,格式化输出字符串,注意要加换行符\n,不然每次写的都连在一起了
print(f'用户{username}注册成功')
# 空一行利于区分
elif choice == '2':
username = input('please input your username>>>:').strip()
password = input('please input your password>>>:').strip() # 1.获取用户输入的用户名和密码
with open(r'userinfo.txt', 'r', encoding='utf8') as f: # 2.文本只读模式打开文件
for line in f: # 3.还是一样循环遍历出文件里每一行的字符串 比如 'jason|123\n' 刚刚在格式化输出字符串时密码后是有换行符的
real_name, real_pwd = line.split('|') # 4. 还是一样切割解压赋值给变量名 'jason' '123\n'
if real_name == username and real_pwd.strip('\n') == password: # 5.比对for循环读取的没一行数据与用户输入的数据是否一致
print('登录成功') # 6. 如果一致则说明,用户输入的账号密码正确,如果不一致,不执行if的子代码,继续for循环比对
break
else: # 7,还是与刚刚的套路一样,如果for循环完了还是没发现用户名与密码都对,就执行else的子代码了。1与2模块的整体语法结构一样的
print('用户名或密码错误')
# 空一行利于区分
else:
print('没有该功能编号')
文件内光标移动实战案例(了解)
在实际操作中作用
监测某一个文件是否有新的内容进来,功能代码实现:
import time
with open(r'a.txt', 'rb') as f: # 1.用二进制只读模式打开文件
f.seek(0, 2) # 2.光标移动到文件末尾,并向右移动0个字节,就是不动
while True:
shuju = f.readline() # 3.此时光标已经在文件末尾了,执行一次只读一行的代码,读取肯定是读不到内容的,把读的内容绑定给变量名
if len(shuju) == 0: # 4.判断读的内容的字节长度是不是0,0就确定没有内容
time.sleep(0.5) # 5.这行代码的意思是让代码停0.5秒后再往下执行,目的就是防止while死循环让电脑死机。
else:
print(line.decode('utf8'), end='')
# 6.如果字节长度不是0,说明有新的内容写进来了。先打印读取的第一行,然后继续循环,再在刚刚读取一行的基础上往后再读一行,如果有数据,那就继续打印,以此类推通过循环,将文件新加进来的内容一行一行的读取,但是打印是每一行连在一起打印的出来的。print方法内置末尾是自带换行符的也就是print(line.decode('utf8'), end='\n'),所以你只要不加end=''关键字参数,调用print方法时,实参默认调用的就是默认参数end='\n'。
计算机硬盘修改数据的原理(了解)
硬盘写数据可以看成是在硬盘上刻字 一旦需要修改中间内容 则需要重新刻字
因为刻过的字不可能从中间再分开
硬盘删除数据的原理:
不是直接删除而是改变状态由占有态变为自由态, 等待后续数据的覆盖才会被真正删除!!!
这也是U盘等存储器在删掉数据后,数据还能被恢复的原因。
通过代码修改文件内容的方法(了解)
方式1: 覆盖写!
with open(r'a.txt', 'r', encoding='utf8') as f: # 1.先用只读模式打开出来文件
data = f.read() # 2.将整个读出来的内容赋值给变量名
with open(r'a.txt', 'w', encoding='utf8') as f1: # 3.用只写模式打开出来文件,并清空文件内容
f1.write(data.replace('jason', 'tony')) # 4.通过替换的方法,将变量名绑定的数据中的'jason'替换为 'tony'后,在写入到这个被清空的文件里面去。
这样就完成了文件内的内容修改看似简单的操作,底层的代码是如何实现的
方式2: 换地写!!
先把源文件读出来,修改一下写到另外一个地方变成一个新文件
然后将原文件删除 再将新文件命名成原文件
代码实现:比如原文件叫 a.txt
import os
with open('a.txt', 'r', encoding='utf8') as read_f, \
open('.a.txt.swap', 'w', encoding='utf-8') as write_f:
for line in read_f:
write_f.write(line.replace('tony', 'kevinSB'))
os.remove('a.txt') # 4. 删除a.txt
os.rename('.a.txt.swap', 'a.txt') # 5. 重命名文件
# 1. with后面打开文件可以同时打开多个文件,逗号后面是不需要撬棍符\的,但是连在一起看代码太长了,看的不舒服,可以加个\,然后按下回车,就可以将下一个打开文件的代码放到下一行去了
# 2. 只读模式打开源文件,只写模式创建并打开临时文件
# 3. for循环一行一行的读取源文件,读一行的内容看里面有没有'tony'有的话把替换成 'kevinSB' ,再把这一行内容写入到临时文件里面去,for循环再读源文件的下一行,以此类推,往临时文件里面写,知道for循环完,把所有行都替换完,并写进临时文件后,结束。
函数前戏
循环
相同的代码在相同的位置反复执行
函数
相同的代码在不同的位置反复执行
ps:相同的代码不是真正一模一样而是可以通过传入的数据不同而做出不同的改变
"""
def my_len():
count = 0
for i in name_list:
count += 1
print(count)
my_len()
"""
函数相当于是工具(具有一定功能)
不用函数
修理工需要修理器件要用锤子 原地打造 每次用完就扔掉 下次用继续原地打造
用函数
修理工提前准备好工具 什么时候想用就直接拿出来使用
"""
函数的语法结构
def 函数名(参数):
'''函数注释'''
函数体代码
return 返回值
1.def 定义函数的关键字
2.函数名 命名等同于变量名
3.参数 可有可无 主要是在使用函数的时候规定要不要外界传数据进来
4.函数注释 类似于工具说明书
5.函数体代码 是整个函数的核心 主要取决于程序员的编写!!!
6.return 使用函数之后可以返回给使用者的数据 可有可无
函数的定义与调用
1.函数在定义阶段只检测语法 不执行代码
def func():
pass
2.函数在调用阶段才会执行函数体代码
func()
3.函数必须先定义后调用!!!
4.函数定义使用 关键字def
函数调用使用 函数名加括号
如果有参数则需要在括号内按照相应的规则传递参数(后续详细讲解)
函数的分类
1.空函数
函数体代码为空 使用的pass或者...补全的
空函数主要用于项目前期的功能框架搭建
def register():
"""注册功能"""
pass
2.无参函数
定义函数的时候括号内没有参数
def index():
print('from index function')
3.有参函数
定义函数的时候括号内写参数 调用函数的时候括号传参数
def func(a):
print(a)
.
.
.
函数的返回值!!!!! 重要!!!!
1.什么是返回值 调用函数之后返回给调用者的结果
2.如何获取返回值 变量名 赋值符号 函数的调用
res = func() # 先执行func函数 然后将返回值赋值给变量res
3.函数返回值的多种情况
3.1.函数体代码中没有return关键字 默认返回None
3.2.函数体代码有return 如果后面没有写任何东西还是返回None
3.3.函数体代码有return 后面写什么就返回什么
3.4.函数体代码有return并且后面有多个数据值 则自动组织成元组返回
3.5.函数体代码遇到return会立刻结束!!!!!!!!!!!!!!!!!!!!!!!!!
函数的参数
形式参数
在函数定义阶段括号内填写的参数 简称'形参'
实际参数
在函数调用阶段括号内填写的参数 简称'实参'
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
形参与实参的关系
形参类似于变量名 在函数定义阶段可以随便写 最好见名知意
def register(name,pwd):
pass
实参类似于数据值 在函数调用阶段与形参临时绑定 函数运行结束立刻断开
register('jason',123) 形参name与jason绑定 形参pwd与123绑定
"""
作业
1.整理两天的内容 完成相应作业考核
2.使用函数将员工管理系统和文件进阶注册登录封装
3.预习明日内容
参数、名称空间、作用域
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY