文件的光标、修改,函数寄基本介绍
今日内容总结
昨日内容的小补充
with上下文管理是可以一次性打开多个文件的。代码示例:
# 昨日作业1优化 source_file_path为拷贝文件路径 target_file_path为拷贝文件到的路径
with open(r'%s' % source_file_path, 'rb') as f1, open(r'%s' % target_file_path, 'wb') as f2:
for line in f1:
f2.write(line)
# 以只读的方式打开打开拷贝文件路径,以只写的方式打开拷贝文件到的路径
文件内光标的移动
光标移动的介绍
在之前的文件内置方法中提到,read()是读取文件内所有内容,执行完该操作后,文件指针会移动到文件末尾,这个时候我们再想read()就做不到了。这是因为第一次read()的时候,光标是在文件最开始一直移动读取,直到最后的。因为光标已经到最后了,你接下来再读取,它也不会移动,也就取不到值了。所以,我们就有了接下来的方法。代码示例:
# a.txt的内容为 Jason NB 鸡哥NB Jason NB 鸡哥NB Jason NB 鸡哥NB
with open(r'a.txt', 'r', encoding='utf8') as f:
print(f.read(3)) # Jas
print(f.read(3)) # on
# read在文本模式下 括号内的数字表示的是读取指定的字符个数
with open(r'a.txt', 'rb') as f:
print(f.read(3).decode('utf8')) # Jas
print(f.read(1).decode('utf8')) # o
# read在二进制模式下 括号内的数字表示的是读取指定的字节数
控制光标的移动
seek方法可以控制光标的移动,在文本模式下移动的单位也是字节数。其中,seek方法可以这样表示:seek(offset,whence)。offset表示控制移动的字节数,whence表示控制模式。接下来是对三个模式的基本使用代码示例:
# 0模式的使用
with open('a.txt',mode='rt',encoding='utf-8') as f:
f.seek(3,0) # 参照文件开头移动了3个字节
print(f.tell()) # 查看当前文件光标距离文件开头的位置,输出结果为3
print(f.read()) # 从第3个字节的位置读到文件末尾,输出结果为:你好
# 注意:由于在t模式下,会将读取的内容自动解码,所以必须保证读取的内容是一个完整中文数据,否则解码失败
# 相对于文件开头(让光标先移动到文件开头),支持文本模式和二进制模式
# 1模式的使用
with open('a.txt',mode='rb') as f:
f.seek(3,1) # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头
print(f.tell()) # 输出结果为:3
f.seek(4,1) # 从当前位置往后移动4个字节,而此时的当前位置为3
print(f.tell()) # 输出结果为:7
# 相对于当前位置(让光标先停留在当前位置),只支持二进制模式
# 2.模式的使用
with open('a.txt',mode='rb') as f:
f.seek(0,2) # 参照文件末尾移动0个字节, 即直接跳到文件末尾
print(f.tell()) # 输出结果为:9
f.seek(-3,2) # 参照文件末尾往前移动了3个字节
print(f.read().decode('utf-8')) # 输出结果为:好
# 相对于文件结尾(让光标先移动到文件末尾),只支持二进制模式
# 实时检测文件内是否有新增的内容并打印出来(没有太多的实际意义)
with open('a.txt', mode='rb') as f:
f.seek(0, 2)
while True:
line = f.readline()
if len(line) == 0:
# 没有内容
pass
else:
print(line.decode('utf-8'), end='')
文件的修改
硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容,内存中的数据是可以修改的。而今天鸡哥的课前闲聊中,提到了硬盘上的数据的两个状态,占有态和自由态。
我们删除数据其实就是将数据原来的位置标记成自由态,之后如果有新的数据进来了并且落到了自由态位置那么直接覆盖。
上述主要是让我们了解数据恢复的原理,以及隐私保护,修改文件数据的原理等。而这里我们修改文件的方式分为两种。代码示例:
# 第一种 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件 优点是在文件修改过程中同一份数据只有一份。缺点是会过多的占用内存
with open('a.txt',mode='rt',encoding='utf-8') as f:
data=f.read()
with open('a.txt',mode='wt',encoding='utf-8') as f:
f.write(data.replace('Jason','NB'))
# 第二种 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名 优点是不会占用过多的内存。缺点是在文件修改过程中同一份数据存了两份
import os # 模块(后面会学)
with open('a.txt', 'r', encoding='utf-8') as read_f, \
open('.a.txt.swap', 'w', encoding='utf-8') as wrife_f:
for line in read_f:
wrife_f.write(line.replace('jason', 'jerry'))
os.remove('a.txt') # 删除文件
os.rename('.a.txt.swap', 'b.txt') # 重命名文件
函数简介
函数,其实相当于是工具,创建函数,就是创建工具,函数的使用,就是对工具的使用。在之前的学习中,我们会发现,有些代码,我们是需要重复使用的,而为了不每次需要这串代码,我们都重新敲一遍。所以函数的使用,就出现了。我们将这串代码设置为函数,定义给一个函数名(与变量名一样),这样我们在需要使用这串代码时,调用该函数方法就可以了。调用函数需要使用函数名加括号。代码示例:
# 以代码的方式实现len(在不使用len方法的情况下统计元素个数)
a = [1, 2, 3, 4]
print(len(a)) # 4
n = 0
for i in a:
n += 1
print(n) # 4
def m_len():
n = 0
for i in a:
n += 1
print(n)
m_len() # 4
# 虽然上述方式实现了不借助与len完成元素个数的统计,但是需要反复的编写相同的代码,也就是说我们只能统计变量a的元素个数
# 同时我们发现了,以前使用的数据类型的内置方法,其实也叫数据类型的内置函数。
函数的语法结构
def 函数名(参数1, 参数2...):
'''函数的注释'''
函数体代码
return # 返回值
def def就是定义函数的关键字。函数名,类似于变量名 指代函数体代码,命名与变量名一致。括号,在定义函数的时候,函数名后面一定是括号,括号内可以写参数,参数,似于使用函数的时候 给函数内部传递的数据,可以不写,或者单个、多个。冒号,定义函数的函数体代码时需要有缩进的。函数的注释,用于解释函数的主要功能、使用方法等说明性文字。函数体代码,函数的核心功能 也是我们将来编写的核心。return,后面跟什么 那么执行完函数之后就会返回什么。
值得注意的是,定义函数的过程不会执行函数体代码 只会检测语法。也就是说,我们只要不执行,写错了也不会报错,但是要符合语法。语法错误的话,就会报错,代码示例:
def index():
xsadasd # 定义的时候不会报错
def index1():
if # 语法错误定义的时候就会报错
今日作业、
# 1.登录注册的重复练习
data_list = ['jason|123', ]
j = 0
while j < 3:
print('输入1注册,输入2登录,输入3退出')
num = input('请输入功能>>>:').strip()
a = 1
if num == '1':
username = input('username>>>:').strip()
password = input('password>>>:').strip()
for i in data_list:
if username == i.split('|')[0]:
print('该用户已存在')
break
else:
data = f'{username}|{password}'
data_list.append(data)
elif num == '2':
username = input('username>>>:').strip()
password = input('password>>>:').strip()
for i in data_list:
if username == i.split('|')[0]:
if password == i.split('|')[1]:
print('登录成功')
a = 0
break
else:
print('密码错误')
j += 1
else:
j += 1
if a == 1:
print('用户名不存在')
else:
print('退出成功')
break
# 2.尝试使用函数写登录注册
data_list = ['jason|123', ]
def register():
for i in data_list:
if username == i.split('|')[0]:
print('该用户已存在')
break
else:
data = f'{username}|{password}'
data_list.append(data)
def login():
a = 1
for i in data_list:
if username == i.split('|')[0]:
if password == i.split('|')[1]:
print('登录成功')
a = 0
break
else:
print('密码错误')
else:
if a == 1:
print('用户名不存在')
while True:
print('输入1注册,输入2登录,输入3退出')
num = input('请输入功能>>>:').strip()
if num == '1':
username = input('username>>>:').strip()
password = input('password>>>:').strip()
register()
elif num == '2':
username = input('username>>>:').strip()
password = input('password>>>:').strip()
login()
else:
print('退出成功')
break

学习内容总结
浙公网安备 33010602011771号